216 #ifndef NK_SINGLE_FILE
217 #define NK_SINGLE_FILE
220 #ifndef NK_NUKLEAR_H_
221 #define NK_NUKLEAR_H_
233 #define NK_UNDEFINED (-1.0f)
234 #define NK_UTF_INVALID 0xFFFD
235 #define NK_UTF_SIZE 4
237 #define NK_INPUT_MAX 16
239 #ifndef NK_MAX_NUMBER_BUFFER
240 #define NK_MAX_NUMBER_BUFFER 64
242 #ifndef NK_SCROLLBAR_HIDING_TIMEOUT
243 #define NK_SCROLLBAR_HIDING_TIMEOUT 4.0f
254 #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199409L))
255 #define NK_API static inline
256 #elif defined(__cplusplus)
257 #define NK_API static inline
259 #define NK_API static
262 #define NK_API extern
266 #ifdef NK_SINGLE_FILE
267 #define NK_LIB static
269 #define NK_LIB extern
273 #define NK_INTERN static
274 #define NK_STORAGE static
275 #define NK_GLOBAL static
277 #define NK_FLAG(x) (1 << (x))
278 #define NK_STRINGIFY(x) #x
279 #define NK_MACRO_STRINGIFY(x) NK_STRINGIFY(x)
280 #define NK_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1 ## arg2
281 #define NK_STRING_JOIN_DELAY(arg1, arg2) NK_STRING_JOIN_IMMEDIATE(arg1, arg2)
282 #define NK_STRING_JOIN(arg1, arg2) NK_STRING_JOIN_DELAY(arg1, arg2)
285 #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__COUNTER__)
287 #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__LINE__)
290 #ifndef NK_STATIC_ASSERT
291 #define NK_STATIC_ASSERT(exp) typedef char NK_UNIQUE_NAME(_dummy_array)[(exp)?1:-1]
296 #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__COUNTER__)
298 #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__LINE__)
302 #define NK_MIN(a,b) ((a) < (b) ? (a) : (b))
303 #define NK_MAX(a,b) ((a) < (b) ? (b) : (a))
304 #define NK_CLAMP(i,v,x) (NK_MAX(NK_MIN(v,x), i))
306 #ifdef NK_INCLUDE_STANDARD_VARARGS
307 #if defined(_MSC_VER) && (_MSC_VER >= 1600)
309 #define NK_PRINTF_FORMAT_STRING _Printf_format_string_
311 #define NK_PRINTF_FORMAT_STRING
313 #if defined(__GNUC__)
314 #define NK_PRINTF_VARARG_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, fmtargnumber+1)))
315 #define NK_PRINTF_VALIST_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, 0)))
317 #define NK_PRINTF_VARARG_FUNC(fmtargnumber)
318 #define NK_PRINTF_VALIST_FUNC(fmtargnumber)
329 #ifdef NK_INCLUDE_FIXED_TYPES
332 #define NK_INT8 int8_t
333 #define NK_UINT8 uint8_t
334 #define NK_INT16 int16_t
335 #define NK_UINT16 uint16_t
336 #define NK_INT32 int32_t
337 #define NK_UINT32 uint32_t
338 #define NK_SIZE_TYPE uintptr_t
339 #define NK_POINTER_TYPE uintptr_t
342 #define NK_INT8 signed char
345 #define NK_UINT8 unsigned char
348 #define NK_INT16 signed short
351 #define NK_UINT16 unsigned short
354 #if defined(_MSC_VER)
355 #define NK_INT32 __int32
357 #define NK_INT32 signed int
361 #if defined(_MSC_VER)
362 #define NK_UINT32 unsigned __int32
364 #define NK_UINT32 unsigned int
368 #if defined(_WIN64) && defined(_MSC_VER)
369 #define NK_SIZE_TYPE unsigned __int64
370 #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
371 #define NK_SIZE_TYPE unsigned __int32
372 #elif defined(__GNUC__) || defined(__clang__)
373 #if defined(__x86_64__) || defined(__ppc64__)
374 #define NK_SIZE_TYPE unsigned long
376 #define NK_SIZE_TYPE unsigned int
379 #define NK_SIZE_TYPE unsigned long
382 #ifndef NK_POINTER_TYPE
383 #if defined(_WIN64) && defined(_MSC_VER)
384 #define NK_POINTER_TYPE unsigned __int64
385 #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
386 #define NK_POINTER_TYPE unsigned __int32
387 #elif defined(__GNUC__) || defined(__clang__)
388 #if defined(__x86_64__) || defined(__ppc64__)
389 #define NK_POINTER_TYPE unsigned long
391 #define NK_POINTER_TYPE unsigned int
394 #define NK_POINTER_TYPE unsigned long
434 struct nk_draw_command;
442 struct nk_draw_vertex_layout_element;
446 struct nk_style_slide;
548 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
655 #ifdef NK_INCLUDE_COMMAND_USERDATA
1211 #define nk_foreach(c, ctx) for((c) = nk__begin(ctx); (c) != 0; (c) = nk__next(ctx,c))
1212 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
1288 NK_API const struct nk_draw_command* nk__draw_next(
const struct nk_draw_command*,
const struct nk_buffer*,
const struct nk_context*);
1302 #define nk_draw_foreach(cmd,ctx, b) for((cmd)=nk__draw_begin(ctx, b); (cmd)!=0; (cmd)=nk__draw_next(cmd, b, ctx))
2857 #define nk_tree_push(ctx, type, title, state) nk_tree_push_hashed(ctx, type, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
2874 #define nk_tree_push_id(ctx, type, title, state, id) nk_tree_push_hashed(ctx, type, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
2917 #define nk_tree_image_push(ctx, type, img, title, state) nk_tree_image_push_hashed(ctx, type, img, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
2937 #define nk_tree_image_push_id(ctx, type, img, title, state, id) nk_tree_image_push_hashed(ctx, type, img, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
3015 #define nk_tree_element_push(ctx, type, title, state, sel) nk_tree_element_push_hashed(ctx, type, title, state, sel, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
3016 #define nk_tree_element_push_id(ctx, type, title, state, sel, id) nk_tree_element_push_hashed(ctx, type, title, state, sel, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
3096 #ifdef NK_INCLUDE_STANDARD_VARARGS
3097 NK_API void nk_labelf(
struct nk_context*,
nk_flags, NK_PRINTF_FORMAT_STRING
const char*, ...) NK_PRINTF_VARARG_FUNC(3);
3099 NK_API void nk_labelf_wrap(struct
nk_context*, NK_PRINTF_FORMAT_STRING const
char*,...) NK_PRINTF_VARARG_FUNC(2);
3100 NK_API void nk_labelf_colored_wrap(struct
nk_context*, struct
nk_color, NK_PRINTF_FORMAT_STRING const
char*,...) NK_PRINTF_VARARG_FUNC(3);
3101 NK_API void nk_labelfv(struct
nk_context*,
nk_flags, NK_PRINTF_FORMAT_STRING const
char*, va_list) NK_PRINTF_VALIST_FUNC(3);
3103 NK_API void nk_labelfv_wrap(struct
nk_context*, NK_PRINTF_FORMAT_STRING const
char*, va_list) NK_PRINTF_VALIST_FUNC(2);
3104 NK_API void nk_labelfv_colored_wrap(struct
nk_context*, struct
nk_color, NK_PRINTF_FORMAT_STRING const
char*, va_list) NK_PRINTF_VALIST_FUNC(3);
3107 NK_API void nk_value_uint(struct
nk_context*, const
char *prefix,
unsigned int);
3528 #ifdef NK_INCLUDE_STANDARD_VARARGS
3529 NK_API void nk_tooltipf(
struct nk_context*, NK_PRINTF_FORMAT_STRING
const char*, ...) NK_PRINTF_VARARG_FUNC(2);
3530 NK_API void nk_tooltipfv(struct
nk_context*, NK_PRINTF_FORMAT_STRING const
char*, va_list) NK_PRINTF_VALIST_FUNC(2);
3896 struct nk_user_font_glyph;
3899 struct nk_user_font_glyph *glyph,
3902 #if defined(NK_INCLUDE_VERTEX_BUFFER_OUTPUT) || defined(NK_INCLUDE_SOFTWARE_FONT)
3903 struct nk_user_font_glyph {
3908 float width, height;
3922 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
3930 #ifdef NK_INCLUDE_FONT_BAKING
3931 enum nk_font_coord_type {
3937 struct nk_baked_font {
3940 float ascent, descent;
3950 struct nk_font_config {
3951 struct nk_font_config *next;
3960 unsigned char ttf_data_owned_by_atlas;
3962 unsigned char merge_mode;
3964 unsigned char pixel_snap;
3966 unsigned char oversample_v, oversample_h;
3968 unsigned char padding[3];
3972 enum nk_font_coord_type coord_type;
3978 struct nk_baked_font *font;
3982 struct nk_font_config *n;
3983 struct nk_font_config *p;
3986 struct nk_font_glyph {
3989 float x0, y0, x1, y1, w, h;
3990 float u0, v0, u1, v1;
3994 struct nk_font *next;
3996 struct nk_baked_font info;
3998 struct nk_font_glyph *glyphs;
3999 const struct nk_font_glyph *fallback;
4002 struct nk_font_config *config;
4005 enum nk_font_atlas_format {
4006 NK_FONT_ATLAS_ALPHA8,
4007 NK_FONT_ATLAS_RGBA32
4010 struct nk_font_atlas {
4022 struct nk_font_glyph *glyphs;
4023 struct nk_font *default_font;
4024 struct nk_font *fonts;
4025 struct nk_font_config *config;
4035 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4036 NK_API void nk_font_atlas_init_default(
struct nk_font_atlas*);
4040 NK_API void nk_font_atlas_begin(
struct nk_font_atlas*);
4041 NK_API struct nk_font_config nk_font_config(float pixel_height);
4042 NK_API struct nk_font *nk_font_atlas_add(
struct nk_font_atlas*,
const struct nk_font_config*);
4043 #ifdef NK_INCLUDE_DEFAULT_FONT
4044 NK_API struct nk_font* nk_font_atlas_add_default(
struct nk_font_atlas*,
float height,
const struct nk_font_config*);
4046 NK_API struct nk_font* nk_font_atlas_add_from_memory(
struct nk_font_atlas *atlas,
void *memory,
nk_size size,
float height,
const struct nk_font_config *config);
4047 #ifdef NK_INCLUDE_STANDARD_IO
4048 NK_API struct nk_font* nk_font_atlas_add_from_file(
struct nk_font_atlas *atlas,
const char *file_path,
float height,
const struct nk_font_config*);
4050 NK_API struct nk_font *nk_font_atlas_add_compressed(
struct nk_font_atlas*,
void *memory,
nk_size size,
float height,
const struct nk_font_config*);
4051 NK_API struct nk_font* nk_font_atlas_add_compressed_base85(
struct nk_font_atlas*,
const char *data,
float height,
const struct nk_font_config *config);
4052 NK_API const void* nk_font_atlas_bake(
struct nk_font_atlas*,
int *width,
int *height,
enum nk_font_atlas_format);
4054 NK_API const struct nk_font_glyph* nk_font_find_glyph(
struct nk_font*,
nk_rune unicode);
4055 NK_API void nk_font_atlas_cleanup(
struct nk_font_atlas *atlas);
4056 NK_API void nk_font_atlas_clear(
struct nk_font_atlas*);
4140 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4170 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4239 #ifndef NK_TEXTEDIT_UNDOSTATECOUNT
4240 #define NK_TEXTEDIT_UNDOSTATECOUNT 99
4243 #ifndef NK_TEXTEDIT_UNDOCHARCOUNT
4244 #define NK_TEXTEDIT_UNDOCHARCOUNT 999
4311 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4401 #ifdef NK_INCLUDE_COMMAND_USERDATA
4537 unsigned short w,
unsigned short h,
nk_handle callback_data);
4573 NK_API void nk_stroke_curve(
struct nk_command_buffer*,
float,
float,
float,
float,
float,
float,
float,
float,
float line_thickness,
struct nk_color);
4652 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
4666 #ifdef NK_UINT_DRAW_INDEX
4667 typedef nk_uint nk_draw_index;
4671 enum nk_draw_list_stroke {
4678 enum nk_draw_vertex_layout_attribute {
4682 NK_VERTEX_ATTRIBUTE_COUNT
4685 enum nk_draw_vertex_layout_format {
4695 NK_FORMAT_COLOR_BEGIN,
4696 NK_FORMAT_R8G8B8 = NK_FORMAT_COLOR_BEGIN,
4697 NK_FORMAT_R16G15B16,
4698 NK_FORMAT_R32G32B32,
4702 NK_FORMAT_R16G15B16A16,
4703 NK_FORMAT_R32G32B32A32,
4704 NK_FORMAT_R32G32B32A32_FLOAT,
4705 NK_FORMAT_R32G32B32A32_DOUBLE,
4709 NK_FORMAT_COLOR_END = NK_FORMAT_RGBA32,
4713 #define NK_VERTEX_LAYOUT_END NK_VERTEX_ATTRIBUTE_COUNT,NK_FORMAT_COUNT,0
4714 struct nk_draw_vertex_layout_element {
4715 enum nk_draw_vertex_layout_attribute attribute;
4716 enum nk_draw_vertex_layout_format format;
4720 struct nk_draw_command {
4721 unsigned int elem_count;
4727 #ifdef NK_INCLUDE_COMMAND_USERDATA
4732 struct nk_draw_list {
4734 struct nk_vec2 circle_vtx[12];
4741 unsigned int element_count;
4742 unsigned int vertex_count;
4743 unsigned int cmd_count;
4746 unsigned int path_count;
4747 unsigned int path_offset;
4752 #ifdef NK_INCLUDE_COMMAND_USERDATA
4758 NK_API void nk_draw_list_init(
struct nk_draw_list*);
4762 #define nk_draw_list_foreach(cmd, can, b) for((cmd)=nk__draw_list_begin(can, b); (cmd)!=0; (cmd)=nk__draw_list_next(cmd, b, can))
4763 NK_API const struct nk_draw_command* nk__draw_list_begin(
const struct nk_draw_list*,
const struct nk_buffer*);
4764 NK_API const struct nk_draw_command* nk__draw_list_next(
const struct nk_draw_command*,
const struct nk_buffer*,
const struct nk_draw_list*);
4765 NK_API const struct nk_draw_command* nk__draw_list_end(
const struct nk_draw_list*,
const struct nk_buffer*);
4768 NK_API void nk_draw_list_path_clear(
struct nk_draw_list*);
4769 NK_API void nk_draw_list_path_line_to(
struct nk_draw_list*,
struct nk_vec2 pos);
4770 NK_API void nk_draw_list_path_arc_to_fast(
struct nk_draw_list*,
struct nk_vec2 center,
float radius,
int a_min,
int a_max);
4771 NK_API void nk_draw_list_path_arc_to(
struct nk_draw_list*,
struct nk_vec2 center,
float radius,
float a_min,
float a_max,
unsigned int segments);
4772 NK_API void nk_draw_list_path_rect_to(
struct nk_draw_list*,
struct nk_vec2 a,
struct nk_vec2 b,
float rounding);
4773 NK_API void nk_draw_list_path_curve_to(
struct nk_draw_list*,
struct nk_vec2 p2,
struct nk_vec2 p3,
struct nk_vec2 p4,
unsigned int num_segments);
4774 NK_API void nk_draw_list_path_fill(
struct nk_draw_list*,
struct nk_color);
4775 NK_API void nk_draw_list_path_stroke(
struct nk_draw_list*,
struct nk_color,
enum nk_draw_list_stroke closed,
float thickness);
4779 NK_API void nk_draw_list_stroke_rect(
struct nk_draw_list*,
struct nk_rect rect,
struct nk_color,
float rounding,
float thickness);
4781 NK_API void nk_draw_list_stroke_circle(
struct nk_draw_list*,
struct nk_vec2 center,
float radius,
struct nk_color,
unsigned int segs,
float thickness);
4783 NK_API void nk_draw_list_stroke_poly_line(
struct nk_draw_list*,
const struct nk_vec2 *pnts,
const unsigned int cnt,
struct nk_color,
enum nk_draw_list_stroke,
float thickness,
enum nk_anti_aliasing);
4786 NK_API void nk_draw_list_fill_rect(
struct nk_draw_list*,
struct nk_rect rect,
struct nk_color,
float rounding);
4789 NK_API void nk_draw_list_fill_circle(
struct nk_draw_list*,
struct nk_vec2 center,
float radius,
struct nk_color col,
unsigned int segs);
4794 NK_API void nk_draw_list_add_text(
struct nk_draw_list*,
const struct nk_user_font*,
struct nk_rect,
const char *text,
int len,
float font_height,
struct nk_color);
4795 #ifdef NK_INCLUDE_COMMAND_USERDATA
4796 NK_API void nk_draw_list_push_userdata(
struct nk_draw_list*,
nk_handle userdata);
5246 #ifndef NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS
5247 #define NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS 16
5249 #ifndef NK_CHART_MAX_SLOT
5250 #define NK_CHART_MAX_SLOT 4
5348 #ifndef NK_WINDOW_MAX_NAME
5349 #define NK_WINDOW_MAX_NAME 64
5461 #ifndef NK_BUTTON_BEHAVIOR_STACK_SIZE
5462 #define NK_BUTTON_BEHAVIOR_STACK_SIZE 8
5465 #ifndef NK_FONT_STACK_SIZE
5466 #define NK_FONT_STACK_SIZE 8
5469 #ifndef NK_STYLE_ITEM_STACK_SIZE
5470 #define NK_STYLE_ITEM_STACK_SIZE 16
5473 #ifndef NK_FLOAT_STACK_SIZE
5474 #define NK_FLOAT_STACK_SIZE 32
5477 #ifndef NK_VECTOR_STACK_SIZE
5478 #define NK_VECTOR_STACK_SIZE 16
5481 #ifndef NK_FLAGS_STACK_SIZE
5482 #define NK_FLAGS_STACK_SIZE 32
5485 #ifndef NK_COLOR_STACK_SIZE
5486 #define NK_COLOR_STACK_SIZE 32
5489 #define NK_CONFIGURATION_STACK_TYPE(prefix, name, type)\
5490 struct nk_config_stack_##name##_element {\
5491 prefix##_##type *address;\
5492 prefix##_##type old_value;\
5494 #define NK_CONFIG_STACK(type,size)\
5495 struct nk_config_stack_##type {\
5497 struct nk_config_stack_##type##_element elements[size];\
5500 #define nk_float float
5519 struct nk_config_stack_float
floats;
5520 struct nk_config_stack_vec2
vectors;
5521 struct nk_config_stack_flags
flags;
5522 struct nk_config_stack_color
colors;
5523 struct nk_config_stack_user_font
fonts;
5530 #define NK_VALUE_PAGE_CAPACITY \
5531 (((NK_MAX(sizeof(struct nk_window),sizeof(struct nk_panel)) / sizeof(nk_uint))) / 2)
5584 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
5585 struct nk_draw_list draw_list;
5587 #ifdef NK_INCLUDE_COMMAND_USERDATA
5614 #define NK_PI 3.141592654f
5615 #define NK_UTF_INVALID 0xFFFD
5616 #define NK_MAX_FLOAT_PRECISION 2
5618 #define NK_UNUSED(x) ((void)(x))
5619 #define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x)))
5620 #define NK_LEN(a) (sizeof(a)/sizeof(a)[0])
5621 #define NK_ABS(a) (((a) < 0) ? -(a) : (a))
5622 #define NK_BETWEEN(x, a, b) ((a) <= (x) && (x) < (b))
5623 #define NK_INBOX(px, py, x, y, w, h)\
5624 (NK_BETWEEN(px,x,x+w) && NK_BETWEEN(py,y,y+h))
5625 #define NK_INTERSECT(x0, y0, w0, h0, x1, y1, w1, h1) \
5626 (!(((x1 > (x0 + w0)) || ((x1 + w1) < x0) || (y1 > (y0 + h0)) || (y1 + h1) < y0)))
5627 #define NK_CONTAINS(x, y, w, h, bx, by, bw, bh)\
5628 (NK_INBOX(x,y, bx, by, bw, bh) && NK_INBOX(x+w,y+h, bx, by, bw, bh))
5630 #define nk_vec2_sub(a, b) nk_vec2((a).x - (b).x, (a).y - (b).y)
5631 #define nk_vec2_add(a, b) nk_vec2((a).x + (b).x, (a).y + (b).y)
5632 #define nk_vec2_len_sqr(a) ((a).x*(a).x+(a).y*(a).y)
5633 #define nk_vec2_muls(a, t) nk_vec2((a).x * (t), (a).y * (t))
5635 #define nk_ptr_add(t, p, i) ((t*)((void*)((nk_byte*)(p) + (i))))
5636 #define nk_ptr_add_const(t, p, i) ((const t*)((const void*)((const nk_byte*)(p) + (i))))
5637 #define nk_zero_struct(s) nk_zero(&s, sizeof(s))
5643 #if defined(__PTRDIFF_TYPE__)
5644 # define NK_UINT_TO_PTR(x) ((void*)(__PTRDIFF_TYPE__)(x))
5645 # define NK_PTR_TO_UINT(x) ((nk_size)(__PTRDIFF_TYPE__)(x))
5646 #elif !defined(__GNUC__)
5647 # define NK_UINT_TO_PTR(x) ((void*)&((char*)0)[x])
5648 # define NK_PTR_TO_UINT(x) ((nk_size)(((char*)x)-(char*)0))
5649 #elif defined(NK_USE_FIXED_TYPES)
5650 # define NK_UINT_TO_PTR(x) ((void*)(uintptr_t)(x))
5651 # define NK_PTR_TO_UINT(x) ((uintptr_t)(x))
5653 # define NK_UINT_TO_PTR(x) ((void*)(x))
5654 # define NK_PTR_TO_UINT(x) ((nk_size)(x))
5657 #define NK_ALIGN_PTR(x, mask)\
5658 (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x) + (mask-1)) & ~(mask-1))))
5659 #define NK_ALIGN_PTR_BACK(x, mask)\
5660 (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x)) & ~(mask-1))))
5662 #define NK_OFFSETOF(st,m) ((nk_ptr)&(((st*)0)->m))
5663 #define NK_CONTAINER_OF(ptr,type,member)\
5664 (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member)))
5671 template<
typename T>
struct nk_alignof;
5672 template<
typename T,
int size_diff>
struct nk_helper{
enum {value = size_diff};};
5673 template<
typename T>
struct nk_helper<T,0>{
enum {value = nk_alignof<T>::value};};
5674 template<
typename T>
struct nk_alignof{
struct Big {T x;
char c;};
enum {
5675 diff =
sizeof(Big) -
sizeof(T), value = nk_helper<Big, diff>::value};};
5676 #define NK_ALIGNOF(t) (nk_alignof<t>::value)
5677 #elif defined(_MSC_VER)
5678 #define NK_ALIGNOF(t) (__alignof(t))
5680 #define NK_ALIGNOF(t) ((char*)(&((struct {char c; t _h;}*)0)->_h) - (char*)0)
5685 #ifdef NK_IMPLEMENTATION
5687 #ifndef NK_INTERNAL_H
5688 #define NK_INTERNAL_H
5690 #ifndef NK_POOL_DEFAULT_CAPACITY
5691 #define NK_POOL_DEFAULT_CAPACITY 16
5694 #ifndef NK_DEFAULT_COMMAND_BUFFER_SIZE
5695 #define NK_DEFAULT_COMMAND_BUFFER_SIZE (4*1024)
5698 #ifndef NK_BUFFER_DEFAULT_INITIAL_SIZE
5699 #define NK_BUFFER_DEFAULT_INITIAL_SIZE (4*1024)
5703 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
5706 #ifdef NK_INCLUDE_STANDARD_IO
5709 #ifdef NK_INCLUDE_STANDARD_VARARGS
5714 #define NK_ASSERT(expr) assert(expr)
5718 #define NK_MEMSET nk_memset
5721 #define NK_MEMCPY nk_memcopy
5724 #define NK_SQRT nk_sqrt
5727 #define NK_SIN nk_sin
5730 #define NK_COS nk_cos
5733 #define NK_STRTOD nk_strtod
5736 #define NK_DTOA nk_dtoa
5739 #define NK_DEFAULT (-1)
5741 #ifndef NK_VSNPRINTF
5746 #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) ||\
5747 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
5748 (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) ||\
5749 (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) ||\
5750 defined(_ISOC99_SOURCE) || defined(_BSD_SOURCE)
5751 #define NK_VSNPRINTF(s,n,f,a) vsnprintf(s,n,f,a)
5753 #define NK_VSNPRINTF(s,n,f,a) vsprintf(s,f,a)
5757 #define NK_SCHAR_MIN (-127)
5758 #define NK_SCHAR_MAX 127
5759 #define NK_UCHAR_MIN 0
5760 #define NK_UCHAR_MAX 256
5761 #define NK_SSHORT_MIN (-32767)
5762 #define NK_SSHORT_MAX 32767
5763 #define NK_USHORT_MIN 0
5764 #define NK_USHORT_MAX 65535
5765 #define NK_SINT_MIN (-2147483647)
5766 #define NK_SINT_MAX 2147483647
5767 #define NK_UINT_MIN 0
5768 #define NK_UINT_MAX 4294967295u
5783 NK_GLOBAL const struct nk_rect nk_null_rect = {-8192.0f, -8192.0f, 16384, 16384};
5784 #define NK_FLOAT_PRECISION 0.00000000000001
5794 #define nk_widget_state_reset(s)\
5795 if ((*(s)) & NK_WIDGET_STATE_MODIFIED)\
5796 (*(s)) = NK_WIDGET_STATE_INACTIVE|NK_WIDGET_STATE_MODIFIED;\
5797 else (*(s)) = NK_WIDGET_STATE_INACTIVE;
5800 NK_LIB float nk_inv_sqrt(
float n);
5801 NK_LIB float nk_sqrt(
float x);
5802 NK_LIB float nk_sin(
float x);
5803 NK_LIB float nk_cos(
float x);
5807 NK_LIB void nk_unify(
struct nk_rect *clip,
const struct nk_rect *a,
float x0,
float y0,
float x1,
float y1);
5808 NK_LIB double nk_pow(
double x,
int n);
5809 NK_LIB int nk_ifloord(
double x);
5810 NK_LIB int nk_ifloorf(
float x);
5811 NK_LIB int nk_iceilf(
float x);
5812 NK_LIB int nk_log10(
double n);
5815 enum {NK_DO_NOT_STOP_ON_NEW_LINE, NK_STOP_ON_NEW_LINE};
5816 NK_LIB int nk_is_lower(
int c);
5817 NK_LIB int nk_is_upper(
int c);
5818 NK_LIB int nk_to_upper(
int c);
5819 NK_LIB int nk_to_lower(
int c);
5820 NK_LIB void* nk_memcopy(
void *dst,
const void *src,
nk_size n);
5823 NK_LIB char *nk_itoa(
char *s,
long n);
5824 NK_LIB int nk_string_float_limit(
char *
string,
int prec);
5825 NK_LIB char *nk_dtoa(
char *s,
double n);
5826 NK_LIB int nk_text_clamp(
const struct nk_user_font *font,
const char *text,
int text_len,
float space,
int *glyphs,
float *text_width,
nk_rune *sep_list,
int sep_count);
5827 NK_LIB struct nk_vec2 nk_text_calculate_text_bounds(const struct
nk_user_font *font,
const char *begin,
int byte_len,
float row_height,
const char **remaining,
struct nk_vec2 *out_offset,
int *glyphs,
int op);
5828 #ifdef NK_INCLUDE_STANDARD_VARARGS
5829 NK_LIB int nk_strfmt(
char *buf,
int buf_size,
const char *fmt, va_list args);
5831 #ifdef NK_INCLUDE_STANDARD_IO
5836 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
5866 enum nk_window_insert_location {
5898 NK_LIB int nk_panel_has_header(
nk_flags flags,
const char *title);
5908 NK_LIB float nk_layout_row_calculate_usable_space(
const struct nk_style *style,
enum nk_panel_type type,
float total_space,
int columns);
5939 NK_LIB int nk_do_button_text_symbol(
nk_flags *state,
struct nk_command_buffer *out,
struct nk_rect bounds,
enum nk_symbol_type symbol,
const char *str,
int len,
nk_flags align,
enum nk_button_behavior behavior,
const struct nk_style_button *style,
const struct nk_user_font *font,
const struct nk_input *in);
5941 NK_LIB int nk_do_button_text_image(
nk_flags *state,
struct nk_command_buffer *out,
struct nk_rect bounds,
struct nk_image img,
const char* str,
int len,
nk_flags align,
enum nk_button_behavior behavior,
const struct nk_style_button *style,
const struct nk_user_font *font,
const struct nk_input *in);
5944 enum nk_toggle_type {
5959 NK_LIB float nk_slider_behavior(
nk_flags *state,
struct nk_rect *logical_cursor,
struct nk_rect *visual_cursor,
struct nk_input *in,
struct nk_rect bounds,
float slider_min,
float slider_max,
float slider_value,
float slider_step,
float slider_steps);
5964 NK_LIB float nk_scrollbar_behavior(
nk_flags *state,
struct nk_input *in,
int has_scrolling,
const struct nk_rect *scroll,
const struct nk_rect *cursor,
const struct nk_rect *empty0,
const struct nk_rect *empty1,
float scroll_offset,
float target,
float scroll_step,
enum nk_orientation o);
5966 NK_LIB float nk_do_scrollbarv(
nk_flags *state,
struct nk_command_buffer *out,
struct nk_rect scroll,
int has_scrolling,
float offset,
float target,
float step,
float button_pixel_inc,
const struct nk_style_scrollbar *style,
struct nk_input *in,
const struct nk_user_font *font);
5967 NK_LIB float nk_do_scrollbarh(
nk_flags *state,
struct nk_command_buffer *out,
struct nk_rect scroll,
int has_scrolling,
float offset,
float target,
float step,
float button_pixel_inc,
const struct nk_style_scrollbar *style,
struct nk_input *in,
const struct nk_user_font *font);
5970 NK_LIB void nk_draw_selectable(
struct nk_command_buffer *out,
nk_flags state,
const struct nk_style_selectable *style,
int active,
const struct nk_rect *bounds,
const struct nk_rect *icon,
const struct nk_image *img,
enum nk_symbol_type sym,
const char *
string,
int len,
nk_flags align,
const struct nk_user_font *font);
5972 NK_LIB int nk_do_selectable_image(
nk_flags *state,
struct nk_command_buffer *out,
struct nk_rect bounds,
const char *str,
int len,
nk_flags align,
int *value,
const struct nk_image *img,
const struct nk_style_selectable *style,
const struct nk_input *in,
const struct nk_user_font *font);
5975 NK_LIB void nk_edit_draw_text(
struct nk_command_buffer *out,
const struct nk_style_edit *style,
float pos_x,
float pos_y,
float x_offset,
const char *text,
int byte_len,
float row_height,
const struct nk_user_font *font,
struct nk_color background,
struct nk_color foreground,
int is_selected);
5984 enum nk_property_status {
5985 NK_PROPERTY_DEFAULT,
5989 enum nk_property_filter {
5993 enum nk_property_kind {
6003 struct nk_property_variant {
6004 enum nk_property_kind kind;
6005 union nk_property value;
6006 union nk_property min_value;
6007 union nk_property max_value;
6008 union nk_property step;
6010 NK_LIB struct nk_property_variant nk_property_variant_int(int value, int min_value, int max_value, int step);
6011 NK_LIB struct nk_property_variant nk_property_variant_float(float value, float min_value, float max_value, float step);
6012 NK_LIB struct nk_property_variant nk_property_variant_double(double value, double min_value, double max_value, double step);
6014 NK_LIB void nk_drag_behavior(
nk_flags *state,
const struct nk_input *in,
struct nk_rect drag,
struct nk_property_variant *variant,
float inc_per_pixel);
6017 NK_LIB void nk_do_property(
nk_flags *ws,
struct nk_command_buffer *out,
struct nk_rect property,
const char *name,
struct nk_property_variant *variant,
float inc_per_pixel,
char *buffer,
int *len,
int *state,
int *cursor,
int *select_begin,
int *select_end,
const struct nk_style_property *style,
enum nk_property_filter filter,
struct nk_input *in,
const struct nk_user_font *font,
struct nk_text_edit *text_edit,
enum nk_button_behavior behavior);
6018 NK_LIB void nk_property(
struct nk_context *
ctx,
const char *name,
struct nk_property_variant *variant,
float inc_per_pixel,
const enum nk_property_filter filter);
6059 nk_inv_sqrt(
float n)
6062 const float threehalfs = 1.5f;
6063 union {
nk_uint i;
float f;} conv = {0};
6066 conv.i = 0x5f375A84 - (conv.i >> 1);
6067 conv.f = conv.f * (threehalfs - (x2 * conv.f * conv.f));
6073 return x * nk_inv_sqrt(x);
6078 NK_STORAGE const float a0 = +1.91059300966915117e-31f;
6079 NK_STORAGE const float a1 = +1.00086760103908896f;
6080 NK_STORAGE const float a2 = -1.21276126894734565e-2f;
6081 NK_STORAGE const float a3 = -1.38078780785773762e-1f;
6082 NK_STORAGE const float a4 = -2.67353392911981221e-2f;
6083 NK_STORAGE const float a5 = +2.08026600266304389e-2f;
6084 NK_STORAGE const float a6 = -3.03996055049204407e-3f;
6085 NK_STORAGE const float a7 = +1.38235642404333740e-4f;
6086 return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*a7))))));
6093 NK_STORAGE const float a0 = 9.9995999154986614e-1f;
6094 NK_STORAGE const float a1 = 1.2548995793001028e-3f;
6095 NK_STORAGE const float a2 = -5.0648546280678015e-1f;
6096 NK_STORAGE const float a3 = 1.2942246466519995e-2f;
6097 NK_STORAGE const float a4 = 2.8668384702547972e-2f;
6098 NK_STORAGE const float a5 = 7.3726485210586547e-3f;
6099 NK_STORAGE const float a6 = -3.8510875386947414e-3f;
6100 NK_STORAGE const float a7 = 4.7196604604366623e-4f;
6101 NK_STORAGE const float a8 = -1.8776444013090451e-5f;
6102 return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*(a7 + x*a8)))))));
6117 nk_pow(
double x,
int n)
6122 n = (plus) ? n : -n;
6129 return plus ? r : 1.0 / r;
6132 nk_ifloord(
double x)
6134 x = (double)((
int)x - ((x < 0.0) ? 1 : 0));
6140 x = (float)((
int)x - ((x < 0.0f) ? 1 : 0));
6148 return (x > i) ? i+1: i;
6151 float r = x - (float)t;
6152 return (r > 0.0f) ? t+1: t;
6162 neg = (n < 0) ? 1 : 0;
6163 ret = (neg) ? (
int)-n : (int)n;
6164 while ((ret / 10) > 0) {
6168 if (neg) exp = -exp;
6174 return nk_null_rect;
6197 return nk_rect(pos.x, pos.y, size.x, size.y);
6202 return nk_rect(r[0], r[1], r[2], r[3]);
6207 return nk_recti(r[0], r[1], r[2], r[3]);
6213 ret.
x = r.x; ret.y = r.y;
6220 ret.
x = r.w; ret.y = r.h;
6224 nk_shrink_rect(struct
nk_rect r, float amount)
6227 r.
w =
NK_MAX(r.w, 2 * amount);
6228 r.h =
NK_MAX(r.h, 2 * amount);
6229 res.x = r.x + amount;
6230 res.y = r.y + amount;
6231 res.w = r.w - 2 * amount;
6232 res.h = r.h - 2 * amount;
6239 r.h =
NK_MAX(r.h, 2 * pad.y);
6240 r.x += pad.x; r.y += pad.y;
6249 ret.
x =
x; ret.y =
y;
6271 nk_unify(
struct nk_rect *clip,
const struct nk_rect *a,
float x0,
float y0,
6286 float pad_x,
float pad_y,
enum nk_heading direction)
6288 float w_half, h_half;
6293 r.
w = r.
w - 2 * pad_x;
6294 r.
h = r.
h - 2 * pad_y;
6299 w_half = r.
w / 2.0f;
6300 h_half = r.
h / 2.0f;
6302 if (direction ==
NK_UP) {
6306 }
else if (direction ==
NK_RIGHT) {
6308 result[1] =
nk_vec2(r.
x + r.
w, r.
y + h_half);
6310 }
else if (direction ==
NK_DOWN) {
6313 result[2] =
nk_vec2(r.
x + w_half, r.
y + r.
h);
6330 NK_INTERN int nk_str_match_here(
const char *regexp,
const char *text);
6331 NK_INTERN int nk_str_match_star(
int c,
const char *regexp,
const char *text);
6332 NK_LIB int nk_is_lower(
int c) {
return (c >=
'a' && c <=
'z') || (c >= 0xE0 && c <= 0xFF);}
6333 NK_LIB int nk_is_upper(
int c){
return (c >=
'A' && c <=
'Z') || (c >= 0xC0 && c <= 0xDF);}
6334 NK_LIB int nk_to_upper(
int c) {
return (c >=
'a' && c <=
'z') ? (c - (
'a' -
'A')) : c;}
6335 NK_LIB int nk_to_lower(
int c) {
return (c >=
'A' && c <=
'Z') ? (c - (
'a' +
'A')) : c;}
6338 nk_memcopy(
void *dst0,
const void *src0,
nk_size length)
6341 char *dst = (
char*)dst0;
6342 const char *src = (
const char*)src0;
6343 if (length == 0 || dst == src)
6347 #define nk_wsize sizeof(nk_word)
6348 #define nk_wmask (nk_wsize-1)
6349 #define NK_TLOOP(s) if (t) NK_TLOOP1(s)
6350 #define NK_TLOOP1(s) do { s; } while (--t)
6354 if ((t | (
nk_ptr)dst) & nk_wmask) {
6355 if ((t ^ (
nk_ptr)dst) & nk_wmask || length < nk_wsize)
6358 t = nk_wsize - (t & nk_wmask);
6360 NK_TLOOP1(*dst++ = *src++);
6362 t = length / nk_wsize;
6363 NK_TLOOP(*(nk_word*)(
void*)dst = *(
const nk_word*)(
const void*)src;
6364 src += nk_wsize; dst += nk_wsize);
6365 t = length & nk_wmask;
6366 NK_TLOOP(*dst++ = *src++);
6371 if ((t | (
nk_ptr)dst) & nk_wmask) {
6372 if ((t ^ (
nk_ptr)dst) & nk_wmask || length <= nk_wsize)
6377 NK_TLOOP1(*--dst = *--src);
6379 t = length / nk_wsize;
6380 NK_TLOOP(src -= nk_wsize; dst -= nk_wsize;
6381 *(nk_word*)(
void*)dst = *(
const nk_word*)(
const void*)src);
6382 t = length & nk_wmask;
6383 NK_TLOOP(*--dst = *--src);
6394 nk_memset(
void *ptr,
int c0,
nk_size size)
6396 #define nk_word unsigned
6397 #define nk_wsize sizeof(nk_word)
6398 #define nk_wmask (nk_wsize - 1)
6405 if (
sizeof(
unsigned int) > 2)
6411 if (size < 3 * nk_wsize) {
6412 while (size--) *dst++ = (
nk_byte)c0;
6426 t = size / nk_wsize;
6428 *(nk_word*)((
void*)dst) = c;
6433 t = (size & nk_wmask);
6445 nk_zero(
void *ptr,
nk_size size)
6448 NK_MEMSET(ptr, 0, size);
6455 while (str && *str++ !=
'\0') siz++;
6459 nk_strtoi(
const char *str,
const char **endptr)
6462 const char *p = str;
6469 while (*p ==
' ') p++;
6474 while (*p && *p >=
'0' && *p <=
'9') {
6475 value = value * 10 + (int) (*p -
'0');
6483 nk_strtod(
const char *str,
const char **endptr)
6487 const char *p = str;
6495 while (*p ==
' ') p++;
6501 while (*p && *p !=
'.' && *p !=
'e') {
6502 value = value * 10.0 + (double) (*p -
'0');
6508 for(m = 0.1; *p && *p !=
'e'; p++ ) {
6509 value = value + (double) (*p -
'0') * m;
6519 }
else if (*p ==
'+') {
6524 for (pow = 0; *p; p++)
6525 pow = pow * 10 + (
int) (*p -
'0');
6527 for (m = 1.0, i = 0; i < pow; i++)
6534 number = value * neg;
6540 nk_strtof(
const char *str,
const char **endptr)
6543 double double_value;
6544 double_value = NK_STRTOD(str, endptr);
6545 float_value = (float)double_value;
6557 if (c1 <= 'Z' && c1 >=
'A') {
6561 if (c2 <= 'Z' && c2 >=
'A') {
6565 return ((d >= 0) << 1) - 1;
6571 nk_stricmpn(
const char *s1,
const char *s2,
int n)
6582 if (c1 <= 'Z' && c1 >=
'A') {
6586 if (c2 <= 'Z' && c2 >=
'A') {
6590 return ((d >= 0) << 1) - 1;
6596 nk_str_match_here(
const char *regexp,
const char *text)
6598 if (regexp[0] ==
'\0')
6600 if (regexp[1] ==
'*')
6601 return nk_str_match_star(regexp[0], regexp+2, text);
6602 if (regexp[0] ==
'$' && regexp[1] ==
'\0')
6603 return *text ==
'\0';
6604 if (*text!=
'\0' && (regexp[0]==
'.' || regexp[0]==*text))
6605 return nk_str_match_here(regexp+1, text+1);
6609 nk_str_match_star(
int c,
const char *regexp,
const char *text)
6612 if (nk_str_match_here(regexp, text))
6614 }
while (*text !=
'\0' && (*text++ == c || c ==
'.'));
6626 if (regexp[0] ==
'^')
6627 return nk_str_match_here(regexp+1, text);
6629 if (nk_str_match_here(regexp, text))
6631 }
while (*text++ !=
'\0');
6636 const char *pattern,
int *out_score)
6643 #define NK_ADJACENCY_BONUS 5
6645 #define NK_SEPARATOR_BONUS 10
6647 #define NK_CAMEL_BONUS 10
6649 #define NK_LEADING_LETTER_PENALTY (-3)
6651 #define NK_MAX_LEADING_LETTER_PENALTY (-9)
6653 #define NK_UNMATCHED_LETTER_PENALTY (-1)
6657 char const * pattern_iter = pattern;
6665 char const * best_letter = 0;
6666 int best_letter_score = 0;
6671 if (!str || !str_len || !pattern)
return 0;
6672 while (str_iter < str_len)
6674 const char pattern_letter = *pattern_iter;
6675 const char str_letter = str[str_iter];
6677 int next_match = *pattern_iter !=
'\0' &&
6678 nk_to_lower(pattern_letter) == nk_to_lower(str_letter);
6679 int rematch = best_letter && nk_to_upper(*best_letter) == nk_to_upper(str_letter);
6681 int advanced = next_match && best_letter;
6682 int pattern_repeat = best_letter && *pattern_iter !=
'\0';
6683 pattern_repeat = pattern_repeat &&
6684 nk_to_lower(*best_letter) == nk_to_lower(pattern_letter);
6686 if (advanced || pattern_repeat) {
6687 score += best_letter_score;
6689 best_letter_score = 0;
6692 if (next_match || rematch)
6696 if (pattern_iter == pattern) {
6697 int count = (int)(&str[str_iter] - str);
6698 int penalty = NK_LEADING_LETTER_PENALTY * count;
6699 if (penalty < NK_MAX_LEADING_LETTER_PENALTY)
6700 penalty = NK_MAX_LEADING_LETTER_PENALTY;
6707 new_score += NK_ADJACENCY_BONUS;
6711 new_score += NK_SEPARATOR_BONUS;
6714 if (prev_lower && nk_is_upper(str_letter))
6715 new_score += NK_CAMEL_BONUS;
6722 if (new_score >= best_letter_score) {
6724 if (best_letter != 0)
6725 score += NK_UNMATCHED_LETTER_PENALTY;
6727 best_letter = &str[str_iter];
6728 best_letter_score = new_score;
6732 score += NK_UNMATCHED_LETTER_PENALTY;
6737 prev_lower = nk_is_lower(str_letter) != 0;
6738 prev_separator = str_letter ==
'_' || str_letter ==
' ';
6745 score += best_letter_score;
6748 if (*pattern_iter !=
'\0')
6761 nk_string_float_limit(
char *
string,
int prec)
6771 if (dot == (prec+1)) {
6778 return (
int)(c - string);
6781 nk_strrev_ascii(
char *s)
6787 for (; i < end; ++i) {
6789 s[i] = s[len - 1 - i];
6794 nk_itoa(
char *s,
long n)
6807 s[i++] = (char)(
'0' + (n % 10));
6818 nk_dtoa(
char *s,
double n)
6821 int digit = 0, m = 0, m1 = 0;
6829 s[0] =
'0'; s[1] =
'\0';
6838 useExp = (m >= 14 || (neg && m >= 9) || m <= -9);
6839 if (neg) *(c++) =
'-';
6845 n = n / (double)nk_pow(10.0, m);
6854 while (n > NK_FLOAT_PRECISION || m >= 0) {
6855 double weight = nk_pow(10.0, m);
6857 double t = (double)n / weight;
6858 digit = nk_ifloord(t);
6859 n -= ((double)digit * weight);
6860 *(c++) = (
char)(
'0' + (char)digit);
6862 if (m == 0 && n > 0)
6879 *(c++) = (
char)(
'0' + (char)(m1 % 10));
6884 for (i = 0, j = m-1; i<j; i++, j--) {
6895 #ifdef NK_INCLUDE_STANDARD_VARARGS
6896 #ifndef NK_INCLUDE_STANDARD_IO
6898 nk_vsnprintf(
char *buf,
int buf_size,
const char *fmt, va_list args)
6903 NK_ARG_TYPE_DEFAULT,
6907 NK_ARG_FLAG_LEFT = 0x01,
6908 NK_ARG_FLAG_PLUS = 0x02,
6909 NK_ARG_FLAG_SPACE = 0x04,
6910 NK_ARG_FLAG_NUM = 0x10,
6911 NK_ARG_FLAG_ZERO = 0x20
6915 enum nk_arg_type arg_type = NK_ARG_TYPE_DEFAULT;
6916 int precision = NK_DEFAULT;
6917 int width = NK_DEFAULT;
6922 const char *iter = fmt;
6925 NK_ASSERT(buf_size);
6926 if (!buf || !buf_size || !fmt)
return 0;
6927 for (iter = fmt; *iter && len < buf_size; iter++) {
6929 while (*iter && (*iter !=
'%') && (len < buf_size))
6930 buf[len++] = *iter++;
6931 if (!(*iter) || len >= buf_size)
break;
6936 if (*iter ==
'-') flag |= NK_ARG_FLAG_LEFT;
6937 else if (*iter ==
'+') flag |= NK_ARG_FLAG_PLUS;
6938 else if (*iter ==
' ') flag |= NK_ARG_FLAG_SPACE;
6939 else if (*iter ==
'#') flag |= NK_ARG_FLAG_NUM;
6940 else if (*iter ==
'0') flag |= NK_ARG_FLAG_ZERO;
6947 if (*iter >=
'1' && *iter <=
'9') {
6953 }
else if (*iter ==
'*') {
6954 width = va_arg(args,
int);
6959 precision = NK_DEFAULT;
6963 precision = va_arg(args,
int);
6976 if (*(iter+1) ==
'h') {
6977 arg_type = NK_ARG_TYPE_CHAR;
6979 }
else arg_type = NK_ARG_TYPE_SHORT;
6981 }
else if (*iter ==
'l') {
6982 arg_type = NK_ARG_TYPE_LONG;
6984 }
else arg_type = NK_ARG_TYPE_DEFAULT;
6988 NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
6989 NK_ASSERT(precision == NK_DEFAULT);
6990 NK_ASSERT(width == NK_DEFAULT);
6993 }
else if (*iter ==
's') {
6995 const char *str = va_arg(args,
const char*);
6996 NK_ASSERT(str != buf &&
"buffer and argument are not allowed to overlap!");
6997 NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
6998 NK_ASSERT(precision == NK_DEFAULT);
6999 NK_ASSERT(width == NK_DEFAULT);
7000 if (str == buf)
return -1;
7001 while (str && *str && len < buf_size)
7002 buf[len++] = *str++;
7003 }
else if (*iter ==
'n') {
7005 signed int *n = va_arg(args,
int*);
7006 NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
7007 NK_ASSERT(precision == NK_DEFAULT);
7008 NK_ASSERT(width == NK_DEFAULT);
7010 }
else if (*iter ==
'c' || *iter ==
'i' || *iter ==
'd') {
7013 const char *num_iter;
7014 int num_len, num_print, padding;
7015 int cur_precision =
NK_MAX(precision, 1);
7016 int cur_width =
NK_MAX(width, 0);
7019 if (arg_type == NK_ARG_TYPE_CHAR)
7020 value = (
signed char)va_arg(args,
int);
7021 else if (arg_type == NK_ARG_TYPE_SHORT)
7022 value = (
signed short)va_arg(args,
int);
7023 else if (arg_type == NK_ARG_TYPE_LONG)
7024 value = va_arg(args,
signed long);
7025 else if (*iter ==
'c')
7026 value = (
unsigned char)va_arg(args,
int);
7027 else value = va_arg(args,
signed int);
7030 nk_itoa(number_buffer, value);
7032 padding =
NK_MAX(cur_width -
NK_MAX(cur_precision, num_len), 0);
7033 if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
7034 padding =
NK_MAX(padding-1, 0);
7037 if (!(flag & NK_ARG_FLAG_LEFT)) {
7038 while (padding-- > 0 && (len < buf_size)) {
7039 if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
7041 else buf[len++] =
' ';
7046 if ((flag & NK_ARG_FLAG_PLUS) && value >= 0 && len < buf_size)
7048 else if ((flag & NK_ARG_FLAG_SPACE) && value >= 0 && len < buf_size)
7052 num_print =
NK_MAX(cur_precision, num_len);
7053 while (precision && (num_print > num_len) && (len < buf_size)) {
7059 num_iter = number_buffer;
7060 while (precision && *num_iter && len < buf_size)
7061 buf[len++] = *num_iter++;
7064 if (flag & NK_ARG_FLAG_LEFT) {
7065 while ((padding-- > 0) && (len < buf_size))
7068 }
else if (*iter ==
'o' || *iter ==
'x' || *iter ==
'X' || *iter ==
'u') {
7070 unsigned long value = 0;
7071 int num_len = 0, num_print, padding = 0;
7072 int cur_precision =
NK_MAX(precision, 1);
7073 int cur_width =
NK_MAX(width, 0);
7074 unsigned int base = (*iter ==
'o') ? 8: (*iter ==
'u')? 10: 16;
7077 const char *upper_output_format =
"0123456789ABCDEF";
7078 const char *lower_output_format =
"0123456789abcdef";
7079 const char *output_format = (*iter ==
'x') ?
7080 lower_output_format: upper_output_format;
7083 if (arg_type == NK_ARG_TYPE_CHAR)
7084 value = (
unsigned char)va_arg(args,
int);
7085 else if (arg_type == NK_ARG_TYPE_SHORT)
7086 value = (
unsigned short)va_arg(args,
int);
7087 else if (arg_type == NK_ARG_TYPE_LONG)
7088 value = va_arg(args,
unsigned long);
7089 else value = va_arg(args,
unsigned int);
7093 int digit = output_format[value % base];
7095 number_buffer[num_len++] = (char)digit;
7097 }
while (value > 0);
7099 num_print =
NK_MAX(cur_precision, num_len);
7100 padding =
NK_MAX(cur_width -
NK_MAX(cur_precision, num_len), 0);
7101 if (flag & NK_ARG_FLAG_NUM)
7102 padding =
NK_MAX(padding-1, 0);
7105 if (!(flag & NK_ARG_FLAG_LEFT)) {
7106 while ((padding-- > 0) && (len < buf_size)) {
7107 if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
7109 else buf[len++] =
' ';
7114 if (num_print && (flag & NK_ARG_FLAG_NUM)) {
7115 if ((*iter ==
'o') && (len < buf_size)) {
7117 }
else if ((*iter ==
'x') && ((len+1) < buf_size)) {
7120 }
else if ((*iter ==
'X') && ((len+1) < buf_size)) {
7125 while (precision && (num_print > num_len) && (len < buf_size)) {
7131 while (num_len > 0) {
7132 if (precision && (len < buf_size))
7133 buf[len++] = number_buffer[num_len-1];
7138 if (flag & NK_ARG_FLAG_LEFT) {
7139 while ((padding-- > 0) && (len < buf_size))
7142 }
else if (*iter ==
'f') {
7144 const char *num_iter;
7145 int cur_precision = (precision < 0) ? 6: precision;
7146 int prefix, cur_width =
NK_MAX(width, 0);
7147 double value = va_arg(args,
double);
7148 int num_len = 0, frac_len = 0, dot = 0;
7151 NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
7152 NK_DTOA(number_buffer, value);
7156 num_iter = number_buffer;
7157 while (*num_iter && *num_iter !=
'.')
7160 prefix = (*num_iter ==
'.')?(
int)(num_iter - number_buffer)+1:0;
7161 padding =
NK_MAX(cur_width - (prefix +
NK_MIN(cur_precision, num_len - prefix)) , 0);
7162 if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
7163 padding =
NK_MAX(padding-1, 0);
7166 if (!(flag & NK_ARG_FLAG_LEFT)) {
7167 while (padding-- > 0 && (len < buf_size)) {
7168 if (flag & NK_ARG_FLAG_ZERO)
7170 else buf[len++] =
' ';
7175 num_iter = number_buffer;
7176 if ((flag & NK_ARG_FLAG_PLUS) && (value >= 0) && (len < buf_size))
7178 else if ((flag & NK_ARG_FLAG_SPACE) && (value >= 0) && (len < buf_size))
7181 if (dot) frac_len++;
7183 buf[len++] = *num_iter;
7184 if (*num_iter ==
'.') dot = 1;
7185 if (frac_len >= cur_precision)
break;
7190 while (frac_len < cur_precision) {
7191 if (!dot && len < buf_size) {
7201 if (flag & NK_ARG_FLAG_LEFT) {
7202 while ((padding-- > 0) && (len < buf_size))
7207 NK_ASSERT(0 &&
"specifier is not supported!");
7211 buf[(len >= buf_size)?(buf_size-1):len] = 0;
7212 result = (len >= buf_size)?-1:len;
7217 nk_strfmt(
char *buf,
int buf_size,
const char *fmt, va_list args)
7221 NK_ASSERT(buf_size);
7222 if (!buf || !buf_size || !fmt)
return 0;
7223 #ifdef NK_INCLUDE_STANDARD_IO
7224 result = NK_VSNPRINTF(buf, (
nk_size)buf_size, fmt, args);
7225 result = (result >= buf_size) ? -1: result;
7226 buf[buf_size-1] = 0;
7228 result = nk_vsnprintf(buf, buf_size, fmt, args);
7237 #define NK_ROTL(x,r) ((x) << (r) | ((x) >> (32 - r)))
7244 const int bsize =
sizeof(k1);
7245 const int nblocks = len/4;
7247 const nk_uint c1 = 0xcc9e2d51;
7248 const nk_uint c2 = 0x1b873593;
7254 for (i = 0; i < nblocks; ++i, keyptr += bsize) {
7256 k1ptr[0] = keyptr[0];
7257 k1ptr[1] = keyptr[1];
7258 k1ptr[2] = keyptr[2];
7259 k1ptr[3] = keyptr[3];
7262 k1 = NK_ROTL(k1,15);
7266 h1 = NK_ROTL(h1,13);
7267 h1 = h1*5+0xe6546b64;
7271 tail = (
const nk_byte*)(data + nblocks*4);
7274 case 3: k1 ^= (
nk_uint)(tail[2] << 16);
7275 case 2: k1 ^= (
nk_uint)(tail[1] << 8u);
7276 case 1: k1 ^= tail[0];
7278 k1 = NK_ROTL(k1,15);
7297 #ifdef NK_INCLUDE_STANDARD_IO
7308 if (!path || !siz || !alloc)
7311 fd = fopen(path,
"rb");
7313 fseek(fd, 0, SEEK_END);
7320 fseek(fd, 0, SEEK_SET);
7327 *siz = (
nk_size)fread(buf, 1,*siz, fd);
7333 nk_text_clamp(
const struct nk_user_font *font,
const char *text,
7334 int text_len,
float space,
int *glyphs,
float *text_width,
7335 nk_rune *sep_list,
int sep_count)
7339 float last_width = 0;
7348 float sep_width = 0;
7349 sep_count =
NK_MAX(sep_count,0);
7352 while (glyph_len && (width < space) && (len < text_len)) {
7355 for (i = 0; i < sep_count; ++i) {
7356 if (unicode != sep_list[i])
continue;
7357 sep_width = last_width = width;
7362 if (i == sep_count){
7363 last_width = sep_width = width;
7367 glyph_len =
nk_utf_decode(&text[len], &unicode, text_len - len);
7370 if (len >= text_len) {
7372 *text_width = last_width;
7376 *text_width = sep_width;
7377 return (!sep_len) ? len: sep_len;
7381 nk_text_calculate_text_bounds(const struct
nk_user_font *font,
7382 const char *begin,
int byte_len,
float row_height,
const char **remaining,
7383 struct nk_vec2 *out_offset,
int *glyphs,
int op)
7385 float line_height = row_height;
7387 float line_width = 0.0f;
7393 if (!begin || byte_len <= 0 || !font)
7397 if (!glyph_len)
return text_size;
7398 glyph_width = font->width(font->userdata, font->height, begin, glyph_len);
7401 while ((text_len < byte_len) && glyph_len) {
7402 if (unicode ==
'\n') {
7403 text_size.
x =
NK_MAX(text_size.
x, line_width);
7404 text_size.
y += line_height;
7407 if (
op == NK_STOP_ON_NEW_LINE)
7411 glyph_len =
nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
7415 if (unicode ==
'\r') {
7418 glyph_len =
nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
7422 *glyphs = *glyphs + 1;
7423 text_len += glyph_len;
7424 line_width += (float)glyph_width;
7425 glyph_len =
nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
7426 glyph_width = font->width(font->userdata, font->height, begin+text_len, glyph_len);
7430 if (text_size.
x < line_width)
7431 text_size.
x = line_width;
7433 *out_offset =
nk_vec2(line_width, text_size.
y + line_height);
7434 if (line_width > 0 || text_size.
y == 0.0f)
7435 text_size.
y += line_height;
7437 *remaining = begin+text_len;
7451 nk_parse_hex(
const char *p,
int length)
7455 while (len < length) {
7457 if (p[len] >=
'a' && p[len] <=
'f')
7458 i += ((p[len] -
'a') + 10);
7459 else if (p[len] >=
'A' && p[len] <=
'F')
7460 i += ((p[len] -
'A') + 10);
7461 else i += (p[len] -
'0');
7480 const char *c = rgb;
7482 col.
r = (
nk_byte)nk_parse_hex(c, 2);
7483 col.g = (
nk_byte)nk_parse_hex(c+2, 2);
7484 col.b = (
nk_byte)nk_parse_hex(c+4, 2);
7492 const char *c = rgb;
7494 col.
r = (
nk_byte)nk_parse_hex(c, 2);
7495 col.g = (
nk_byte)nk_parse_hex(c+2, 2);
7496 col.b = (
nk_byte)nk_parse_hex(c+4, 2);
7497 col.a = (
nk_byte)nk_parse_hex(c+6, 2);
7503 #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
7504 output[0] = (char)NK_TO_HEX((col.
r & 0xF0) >> 4);
7505 output[1] = (char)NK_TO_HEX((col.
r & 0x0F));
7506 output[2] = (char)NK_TO_HEX((col.
g & 0xF0) >> 4);
7507 output[3] = (char)NK_TO_HEX((col.
g & 0x0F));
7508 output[4] = (char)NK_TO_HEX((col.
b & 0xF0) >> 4);
7509 output[5] = (char)NK_TO_HEX((col.
b & 0x0F));
7510 output[6] = (char)NK_TO_HEX((col.
a & 0xF0) >> 4);
7511 output[7] = (char)NK_TO_HEX((col.
a & 0x0F));
7518 #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
7519 output[0] = (char)NK_TO_HEX((col.
r & 0xF0) >> 4);
7520 output[1] = (char)NK_TO_HEX((col.
r & 0x0F));
7521 output[2] = (char)NK_TO_HEX((col.
g & 0xF0) >> 4);
7522 output[3] = (char)NK_TO_HEX((col.
g & 0x0F));
7523 output[4] = (char)NK_TO_HEX((col.
b & 0xF0) >> 4);
7524 output[5] = (char)NK_TO_HEX((col.
b & 0x0F));
7531 return nk_rgba(c[0], c[1], c[2], c[3]);
7536 return nk_rgba(c[0], c[1], c[2], c[3]);
7551 return nk_rgb(c[0], c[1], c[2]);
7556 return nk_rgb(c[0], c[1], c[2]);
7562 ret.
r = (in & 0xFF);
7563 ret.g = ((in >> 8) & 0xFF);
7564 ret.b = ((in >> 16) & 0xFF);
7565 ret.a = (
nk_byte)((in >> 24) & 0xFF);
7581 return nk_rgba_f(c[0], c[1], c[2], c[3]);
7609 nk_hsv(int h, int s, int v)
7616 return nk_hsv(c[0], c[1], c[2]);
7621 return nk_hsv(c[0], c[1], c[2]);
7624 nk_hsv_f(float h, float s, float v)
7634 nk_hsva(int h, int s, int v, int
a)
7636 float hf = ((float)
NK_CLAMP(0, h, 255)) / 255.0f;
7637 float sf = ((float)
NK_CLAMP(0, s, 255)) / 255.0f;
7638 float vf = ((float)
NK_CLAMP(0, v, 255)) / 255.0f;
7639 float af = ((float)
NK_CLAMP(0,
a, 255)) / 255.0f;
7645 return nk_hsva(c[0], c[1], c[2], c[3]);
7650 return nk_hsva(c[0], c[1], c[2], c[3]);
7659 out.
r = v; out.
g = v; out.
b = v; out.
a =
a;
7662 h = h / (60.0f/360.0f);
7666 q = v * (1.0f - (s * f));
7667 t = v * (1.0f - s * (1.0f - f));
7670 case 0:
default: out.r = v; out.g = t; out.b = p;
break;
7671 case 1: out.r = q; out.g = v; out.b = p;
break;
7672 case 2: out.r = p; out.g = v; out.b = t;
break;
7673 case 3: out.r = p; out.g = q; out.b = v;
break;
7674 case 4: out.r = t; out.g = p; out.b = v;
break;
7675 case 5: out.r = v; out.g = p; out.b = q;
break;}
7685 nk_hsva_f(float h, float s, float v, float
a)
7693 return nk_hsva_f(c[0], c[1], c[2], c[3]);
7708 *
r = (float)in.
r * s;
7709 *
g = (
float)in.
g * s;
7710 *
b = (float)in.
b * s;
7711 *
a = (
float)in.
a * s;
7729 *
r = (double)in.
r * s;
7730 *
g = (
double)in.
g * s;
7731 *
b = (double)in.
b * s;
7732 *
a = (
double)in.
a * s;
7753 float *out_v,
float *out_a,
struct nk_colorf in)
7758 const float t = in.
g; in.
g = in.
b; in.
b = t;
7762 const float t = in.
r; in.
r = in.
g; in.
g = t;
7765 chroma = in.
r - ((in.
g < in.
b) ? in.
g: in.
b);
7766 *out_h =
NK_ABS(K + (in.
g - in.
b)/(6.0f * chroma + 1e-20f));
7767 *out_s = chroma / (in.
r + 1e-20f);
7779 float *out_v,
float *out_a,
struct nk_color in)
7796 *out_h = (
nk_byte)(h * 255.0f);
7797 *out_s = (
nk_byte)(s * 255.0f);
7798 *out_v = (
nk_byte)(v * 255.0f);
7871 nk_utf_validate(
nk_rune *u,
int i)
7875 if (!
NK_BETWEEN(*u, nk_utfmin[i], nk_utfmax[i]) ||
7878 for (i = 1; *u > nk_utfmax[i]; ++i);
7882 nk_utf_decode_byte(
char c,
int *i)
7886 for(*i = 0; *i < (int)
NK_LEN(nk_utfmask); ++(*i)) {
7887 if (((
nk_byte)c & nk_utfmask[*i]) == nk_utfbyte[*i])
7888 return (
nk_byte)(c & ~nk_utfmask[*i]);
7895 int i, j, len, type=0;
7901 if (!c || !u)
return 0;
7902 if (!clen)
return 0;
7905 udecoded = nk_utf_decode_byte(c[0], &len);
7909 for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
7910 udecoded = (udecoded << 6) | nk_utf_decode_byte(c[i], &type);
7917 nk_utf_validate(u, len);
7921 nk_utf_encode_byte(
nk_rune u,
int i)
7923 return (
char)((nk_utfbyte[i]) | ((
nk_byte)u & ~nk_utfmask[i]));
7929 len = nk_utf_validate(&u, 0);
7933 for (i = len - 1; i != 0; --i) {
7934 c[i] = nk_utf_encode_byte(u, 0);
7937 c[0] = nk_utf_encode_byte(u, len);
7951 if (!str || !len)
return 0;
7956 while (glyph_len && src_len < len) {
7958 src_len = src_len + glyph_len;
7959 glyph_len =
nk_utf_decode(text + src_len, &unicode, text_len - src_len);
7964 nk_utf_at(
const char *buffer,
int length,
int index,
7977 if (!buffer || !unicode || !len)
return 0;
7994 src_len = src_len + glyph_len;
7995 glyph_len =
nk_utf_decode(text + src_len, unicode, text_len - src_len);
7997 if (i != index)
return 0;
7998 return buffer + src_len;
8010 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
8016 return malloc(size);
8025 nk_buffer_init_default(
struct nk_buffer *buffer)
8028 alloc.userdata.ptr = 0;
8029 alloc.alloc = nk_malloc;
8030 alloc.free = nk_mfree;
8041 NK_ASSERT(initial_size);
8042 if (!b || !a || !initial_size)
return;
8044 nk_zero(b,
sizeof(*b));
8048 b->
size = initial_size;
8058 if (!b || !m || !size)
return;
8060 nk_zero(b,
sizeof(*b));
8067 nk_buffer_align(
void *unaligned,
8110 if (!temp)
return 0;
8114 NK_MEMCPY(temp, b->
memory.
ptr, buffer_size);
8118 if (b->
size == buffer_size) {
8126 back_size = buffer_size - b->
size;
8127 dst =
nk_ptr_add(
void, temp, capacity - back_size);
8129 NK_MEMCPY(dst, src, back_size);
8130 b->
size = capacity - back_size;
8145 if (!b || !size)
return 0;
8152 memory = nk_buffer_align(unaligned, align, &alignment, type);
8177 memory = nk_buffer_align(unaligned, align, &alignment, type);
8181 else b->
size -= (size + alignment);
8190 void *mem = nk_buffer_alloc(b, type, size, align);
8192 NK_MEMCPY(mem, memory, size);
8198 if (!buffer)
return;
8208 if (!buffer)
return;
8250 if (!s || !b)
return;
8261 if (!buffer)
return 0;
8268 if (!buffer)
return 0;
8275 if (!buffer)
return 0;
8288 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
8290 nk_str_init_default(
struct nk_str *str)
8293 alloc.userdata.ptr = 0;
8294 alloc.alloc = nk_malloc;
8295 alloc.free = nk_mfree;
8319 if (!s || !str || !len)
return 0;
8322 NK_MEMCPY(mem, str, (
nk_size)len *
sizeof(
char));
8337 if (!str || !text || !len)
return 0;
8338 for (i = 0; i < len; ++i)
8351 if (!str || !text)
return 0;
8353 glyph_len = byte_len =
nk_utf_decode(text+byte_len, &unicode, 4);
8354 while (unicode !=
'\0' && glyph_len) {
8356 byte_len += glyph_len;
8370 if (!str || !text || !len)
return 0;
8371 for (i = 0; i < len; ++i) {
8373 if (!byte_len)
break;
8385 if (!str || !runes)
return 0;
8386 while (runes[i] !=
'\0') {
8404 NK_ASSERT(len >= 0);
8418 NK_ASSERT(((
int)pos + (
int)len + ((
int)copylen - 1)) >= 0);
8419 NK_ASSERT(((
int)pos + ((
int)copylen - 1)) >= 0);
8422 for (i = 0; i < copylen; ++i) *dst-- = *src--;
8424 NK_MEMCPY(mem, str, (
nk_size)len *
sizeof(
char));
8439 if (!str || !cstr || !len)
return 0;
8444 if (!begin)
return 0;
8466 if (!str || !text || !len)
return 0;
8467 for (i = 0; i < len; ++i)
8480 if (!str || !text)
return 0;
8482 glyph_len = byte_len =
nk_utf_decode(text+byte_len, &unicode, 4);
8483 while (unicode !=
'\0' && glyph_len) {
8485 byte_len += glyph_len;
8499 if (!str || !runes || !len)
return 0;
8500 for (i = 0; i < len; ++i) {
8502 if (!byte_len)
break;
8514 if (!str || !runes)
return 0;
8515 while (runes[i] !=
'\0') {
8526 NK_ASSERT(len >= 0);
8541 NK_ASSERT(len >= 0);
8542 if (!str || len < 0)
return;
8543 if (len >= str->
len) {
8548 index = str->
len - len;
8580 NK_ASSERT(s->
len >= pos + len);
8581 if (s->
len < pos + len)
8614 if (!str || !unicode || !len)
return 0;
8631 src_len = src_len + glyph_len;
8632 glyph_len =
nk_utf_decode(text + src_len, unicode, text_len - src_len);
8634 if (i != pos)
return 0;
8635 return text + src_len;
8657 if (!str || !unicode || !len)
return 0;
8674 src_len = src_len + glyph_len;
8675 glyph_len =
nk_utf_decode(text + src_len, unicode, text_len - src_len);
8677 if (i != pos)
return 0;
8678 return text + src_len;
8746 if (!cb || !b)
return;
8761 b->
clip = nk_null_rect;
8762 #ifdef NK_INCLUDE_COMMAND_USERDATA
8784 unaligned = (
nk_byte*)cmd + size;
8787 #ifdef NK_ZERO_COMMAND_MEMORY
8788 NK_MEMSET(cmd, 0, size + alignment);
8793 #ifdef NK_INCLUDE_COMMAND_USERDATA
8814 cmd->
x = (short)r.
x;
8815 cmd->
y = (
short)r.
y;
8816 cmd->
w = (
unsigned short)
NK_MAX(0, r.
w);
8817 cmd->
h = (
unsigned short)
NK_MAX(0, r.
h);
8821 float x1,
float y1,
float line_thickness,
struct nk_color c)
8830 cmd->
begin.
x = (short)x0;
8831 cmd->
begin.
y = (short)y0;
8832 cmd->
end.
x = (short)x1;
8833 cmd->
end.
y = (short)y1;
8838 float ctrl0x,
float ctrl0y,
float ctrl1x,
float ctrl1y,
8849 cmd->
begin.
x = (short)ax;
8850 cmd->
begin.
y = (short)ay;
8851 cmd->
ctrl[0].
x = (short)ctrl0x;
8852 cmd->
ctrl[0].
y = (short)ctrl0y;
8853 cmd->
ctrl[1].
x = (short)ctrl1x;
8854 cmd->
ctrl[1].
y = (short)ctrl1y;
8855 cmd->
end.
x = (short)bx;
8856 cmd->
end.
y = (short)by;
8865 if (!b || c.
a == 0 || rect.
w == 0 || rect.
h == 0 ||
line_thickness <= 0)
return;
8869 clip->
x, clip->
y, clip->
w, clip->
h))
return;
8876 cmd->
x = (short)rect.
x;
8877 cmd->
y = (
short)rect.
y;
8878 cmd->
w = (
unsigned short)
NK_MAX(0, rect.
w);
8879 cmd->
h = (
unsigned short)
NK_MAX(0, rect.
h);
8888 if (!b || c.
a == 0 || rect.
w == 0 || rect.
h == 0)
return;
8892 clip->
x, clip->
y, clip->
w, clip->
h))
return;
8899 cmd->
x = (short)rect.
x;
8900 cmd->
y = (
short)rect.
y;
8901 cmd->
w = (
unsigned short)
NK_MAX(0, rect.
w);
8902 cmd->
h = (
unsigned short)
NK_MAX(0, rect.
h);
8912 if (!b || rect.
w == 0 || rect.
h == 0)
return;
8916 clip->
x, clip->
y, clip->
w, clip->
h))
return;
8922 cmd->
x = (short)rect.
x;
8923 cmd->
y = (
short)rect.
y;
8924 cmd->
w = (
unsigned short)
NK_MAX(0, rect.
w);
8925 cmd->
h = (
unsigned short)
NK_MAX(0, rect.
h);
8933 float line_thickness,
struct nk_color c)
8947 cmd->
x = (short)r.
x;
8948 cmd->
y = (
short)r.
y;
8949 cmd->
w = (
unsigned short)
NK_MAX(r.
w, 0);
8950 cmd->
h = (
unsigned short)
NK_MAX(r.
h, 0);
8958 if (!b || c.
a == 0 || r.
w == 0 || r.
h == 0)
return;
8968 cmd->
x = (short)r.
x;
8969 cmd->
y = (
short)r.
y;
8970 cmd->
w = (
unsigned short)
NK_MAX(r.
w, 0);
8971 cmd->
h = (
unsigned short)
NK_MAX(r.
h, 0);
8976 float a_min,
float a_max,
float line_thickness,
struct nk_color c)
8984 cmd->
cx = (short)
cx;
8985 cmd->
cy = (short)
cy;
8986 cmd->
r = (
unsigned short)radius;
8993 float a_min,
float a_max,
struct nk_color c)
8997 if (!b || c.
a == 0)
return;
9001 cmd->
cx = (short)
cx;
9002 cmd->
cy = (short)
cy;
9003 cmd->
r = (
unsigned short)radius;
9010 float y1,
float x2,
float y2,
float line_thickness,
struct nk_color c)
9015 if (
b->use_clipping) {
9017 if (!
NK_INBOX(x0, y0, clip->
x, clip->
y, clip->
w, clip->
h) &&
9018 !
NK_INBOX(x1, y1, clip->
x, clip->
y, clip->
w, clip->
h) &&
9027 cmd->
a.
x = (short)x0;
9028 cmd->
a.
y = (short)y0;
9029 cmd->
b.
x = (short)x1;
9030 cmd->
b.
y = (short)y1;
9031 cmd->
c.
x = (short)x2;
9032 cmd->
c.
y = (short)y2;
9037 float y1,
float x2,
float y2,
struct nk_color c)
9041 if (!
b ||
c.a == 0)
return;
9043 if (
b->use_clipping) {
9045 if (!
NK_INBOX(x0, y0, clip->
x, clip->
y, clip->
w, clip->
h) &&
9046 !
NK_INBOX(x1, y1, clip->
x, clip->
y, clip->
w, clip->
h) &&
9054 cmd->
a.
x = (short)x0;
9055 cmd->
a.
y = (short)y0;
9056 cmd->
b.
x = (short)x1;
9057 cmd->
b.
y = (short)y1;
9058 cmd->
c.
x = (short)x2;
9059 cmd->
c.
y = (short)y2;
9064 float line_thickness,
struct nk_color col)
9092 if (!b || col.
a == 0)
return;
9106 float line_thickness,
struct nk_color col)
9141 cmd->
x = (short)r.
x;
9142 cmd->
y = (
short)r.
y;
9143 cmd->
w = (
unsigned short)
NK_MAX(0, r.
w);
9144 cmd->
h = (
unsigned short)
NK_MAX(0, r.
h);
9164 cmd->
x = (short)r.
x;
9165 cmd->
y = (
short)r.
y;
9166 cmd->
w = (
unsigned short)
NK_MAX(0, r.
w);
9167 cmd->
h = (
unsigned short)
NK_MAX(0, r.
h);
9173 const char *
string,
int length,
const struct nk_user_font *font,
9176 float text_width = 0;
9181 if (!b || !
string || !
length || (bg.
a == 0 && fg.
a == 0))
return;
9190 if (text_width > r.
w){
9192 float txt_width = (float)text_width;
9193 length = nk_text_clamp(font,
string, length, r.
w, &glyphs, &txt_width, 0,0);
9196 if (!length)
return;
9200 cmd->
x = (short)r.
x;
9201 cmd->
y = (
short)r.
y;
9202 cmd->
w = (
unsigned short)r.
w;
9203 cmd->
h = (
unsigned short)r.
h;
9222 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
9224 nk_draw_list_init(
struct nk_draw_list *list)
9229 nk_zero(list,
sizeof(*list));
9230 for (i = 0; i <
NK_LEN(list->circle_vtx); ++i) {
9231 const float a = ((float)i / (
float)
NK_LEN(list->circle_vtx)) * 2 *
NK_PI;
9232 list->circle_vtx[i].x = (float)NK_COS(a);
9233 list->circle_vtx[i].y = (float)NK_SIN(a);
9237 nk_draw_list_setup(
struct nk_draw_list *canvas,
const struct nk_convert_config *config,
9244 NK_ASSERT(vertices);
9245 NK_ASSERT(elements);
9246 if (!canvas || !config || !cmds || !vertices || !elements)
9249 canvas->buffer = cmds;
9250 canvas->config = *config;
9251 canvas->elements = elements;
9252 canvas->vertices = vertices;
9253 canvas->line_AA = line_aa;
9254 canvas->shape_AA = shape_aa;
9255 canvas->clip_rect = nk_null_rect;
9257 canvas->cmd_offset = 0;
9258 canvas->element_count = 0;
9259 canvas->vertex_count = 0;
9260 canvas->cmd_offset = 0;
9261 canvas->cmd_count = 0;
9262 canvas->path_count = 0;
9264 NK_API const struct nk_draw_command*
9265 nk__draw_list_begin(
const struct nk_draw_list *canvas,
const struct nk_buffer *buffer)
9269 const struct nk_draw_command *cmd;
9272 if (!buffer || !buffer->
size || !canvas->cmd_count)
9276 offset = buffer->
memory.
size - canvas->cmd_offset;
9277 cmd =
nk_ptr_add(
const struct nk_draw_command, memory, offset);
9280 NK_API const struct nk_draw_command*
9281 nk__draw_list_end(
const struct nk_draw_list *canvas,
const struct nk_buffer *buffer)
9286 const struct nk_draw_command *end;
9290 if (!buffer || !canvas)
9295 offset = size - canvas->cmd_offset;
9296 end =
nk_ptr_add(
const struct nk_draw_command, memory, offset);
9297 end -= (canvas->cmd_count-1);
9300 NK_API const struct nk_draw_command*
9301 nk__draw_list_next(
const struct nk_draw_command *cmd,
9302 const struct nk_buffer *buffer,
const struct nk_draw_list *canvas)
9304 const struct nk_draw_command *end;
9307 if (!cmd || !buffer || !canvas)
9310 end = nk__draw_list_end(canvas, buffer);
9311 if (cmd <= end)
return 0;
9315 nk_draw_list_alloc_path(
struct nk_draw_list *list,
int count)
9322 point_size * (
nk_size)count, point_align);
9324 if (!points)
return 0;
9325 if (!list->path_offset) {
9327 list->path_offset = (
unsigned int)((
nk_byte*)points - (
nk_byte*)memory);
9329 list->path_count += (
unsigned int)count;
9333 nk_draw_list_path_last(struct nk_draw_list *list)
9337 NK_ASSERT(list->path_count);
9340 point += (list->path_count-1);
9344 nk_draw_list_push_command(
struct nk_draw_list *list,
struct nk_rect clip,
9349 struct nk_draw_command *cmd;
9352 cmd = (
struct nk_draw_command*)
9353 nk_buffer_alloc(list->buffer,
NK_BUFFER_BACK, cmd_size, cmd_align);
9356 if (!list->cmd_count) {
9363 cmd->elem_count = 0;
9364 cmd->clip_rect = clip;
9365 cmd->texture = texture;
9366 #ifdef NK_INCLUDE_COMMAND_USERDATA
9367 cmd->userdata = list->userdata;
9371 list->clip_rect = clip;
9375 nk_draw_list_command_last(
struct nk_draw_list *list)
9379 struct nk_draw_command *cmd;
9380 NK_ASSERT(list->cmd_count);
9384 cmd =
nk_ptr_add(
struct nk_draw_command, memory, size - list->cmd_offset);
9385 return (cmd - (list->cmd_count-1));
9388 nk_draw_list_add_clip(
struct nk_draw_list *list,
struct nk_rect rect)
9392 if (!list->cmd_count) {
9393 nk_draw_list_push_command(list, rect, list->config.null.texture);
9395 struct nk_draw_command *prev = nk_draw_list_command_last(list);
9396 if (prev->elem_count == 0)
9397 prev->clip_rect = rect;
9398 nk_draw_list_push_command(list, rect, prev->texture);
9402 nk_draw_list_push_image(
struct nk_draw_list *list,
nk_handle texture)
9406 if (!list->cmd_count) {
9407 nk_draw_list_push_command(list, nk_null_rect, texture);
9409 struct nk_draw_command *prev = nk_draw_list_command_last(list);
9410 if (prev->elem_count == 0) {
9411 prev->texture = texture;
9412 #ifdef NK_INCLUDE_COMMAND_USERDATA
9413 prev->userdata = list->userdata;
9415 }
else if (prev->texture.id != texture.
id
9416 #ifdef NK_INCLUDE_COMMAND_USERDATA
9417 || prev->userdata.id != list->userdata.id
9419 ) nk_draw_list_push_command(list, prev->clip_rect, texture);
9422 #ifdef NK_INCLUDE_COMMAND_USERDATA
9424 nk_draw_list_push_userdata(
struct nk_draw_list *list,
nk_handle userdata)
9426 list->userdata = userdata;
9430 nk_draw_list_alloc_vertices(
struct nk_draw_list *list,
nk_size count)
9434 if (!list)
return 0;
9436 list->config.vertex_size*count, list->config.vertex_alignment);
9438 list->vertex_count += (
unsigned int)count;
9449 if(
sizeof(nk_draw_index)==2) NK_ASSERT((list->vertex_count < NK_USHORT_MAX &&
9450 "To many verticies for 16-bit vertex indicies. Please read comment above on how to solve this problem"));
9454 nk_draw_list_alloc_elements(
struct nk_draw_list *list,
nk_size count)
9457 struct nk_draw_command *cmd;
9461 if (!list)
return 0;
9463 ids = (nk_draw_index*)
9464 nk_buffer_alloc(list->elements,
NK_BUFFER_FRONT, elem_size*count, elem_align);
9466 cmd = nk_draw_list_command_last(list);
9467 list->element_count += (
unsigned int)count;
9468 cmd->elem_count += (
unsigned int)count;
9472 nk_draw_vertex_layout_element_is_end_of_layout(
9473 const struct nk_draw_vertex_layout_element *element)
9475 return (element->attribute == NK_VERTEX_ATTRIBUTE_COUNT ||
9476 element->format == NK_FORMAT_COUNT);
9479 nk_draw_vertex_color(
void *attr,
const float *vals,
9480 enum nk_draw_vertex_layout_format format)
9484 NK_ASSERT(format >= NK_FORMAT_COLOR_BEGIN);
9485 NK_ASSERT(format <= NK_FORMAT_COLOR_END);
9486 if (format < NK_FORMAT_COLOR_BEGIN || format > NK_FORMAT_COLOR_END)
return;
9494 default: NK_ASSERT(0 &&
"Invalid vertex layout color format");
break;
9495 case NK_FORMAT_R8G8B8A8:
9496 case NK_FORMAT_R8G8B8: {
9498 NK_MEMCPY(attr, &col.
r,
sizeof(col));
9500 case NK_FORMAT_B8G8R8A8: {
9503 NK_MEMCPY(attr, &bgra,
sizeof(bgra));
9505 case NK_FORMAT_R16G15B16: {
9507 col[0] = (
nk_ushort)(val[0]*(
float)NK_USHORT_MAX);
9508 col[1] = (
nk_ushort)(val[1]*(
float)NK_USHORT_MAX);
9509 col[2] = (
nk_ushort)(val[2]*(
float)NK_USHORT_MAX);
9510 NK_MEMCPY(attr, col,
sizeof(col));
9512 case NK_FORMAT_R16G15B16A16: {
9514 col[0] = (
nk_ushort)(val[0]*(
float)NK_USHORT_MAX);
9515 col[1] = (
nk_ushort)(val[1]*(
float)NK_USHORT_MAX);
9516 col[2] = (
nk_ushort)(val[2]*(
float)NK_USHORT_MAX);
9517 col[3] = (
nk_ushort)(val[3]*(
float)NK_USHORT_MAX);
9518 NK_MEMCPY(attr, col,
sizeof(col));
9520 case NK_FORMAT_R32G32B32: {
9522 col[0] = (
nk_uint)(val[0]*(
float)NK_UINT_MAX);
9523 col[1] = (
nk_uint)(val[1]*(
float)NK_UINT_MAX);
9524 col[2] = (
nk_uint)(val[2]*(
float)NK_UINT_MAX);
9525 NK_MEMCPY(attr, col,
sizeof(col));
9527 case NK_FORMAT_R32G32B32A32: {
9529 col[0] = (
nk_uint)(val[0]*(
float)NK_UINT_MAX);
9530 col[1] = (
nk_uint)(val[1]*(
float)NK_UINT_MAX);
9531 col[2] = (
nk_uint)(val[2]*(
float)NK_UINT_MAX);
9532 col[3] = (
nk_uint)(val[3]*(
float)NK_UINT_MAX);
9533 NK_MEMCPY(attr, col,
sizeof(col));
9535 case NK_FORMAT_R32G32B32A32_FLOAT:
9536 NK_MEMCPY(attr, val,
sizeof(
float)*4);
9538 case NK_FORMAT_R32G32B32A32_DOUBLE: {
9540 col[0] = (double)val[0];
9541 col[1] = (double)val[1];
9542 col[2] = (double)val[2];
9543 col[3] = (double)val[3];
9544 NK_MEMCPY(attr, col,
sizeof(col));
9546 case NK_FORMAT_RGB32:
9547 case NK_FORMAT_RGBA32: {
9550 NK_MEMCPY(attr, &color,
sizeof(color));
9554 nk_draw_vertex_element(
void *dst,
const float *values,
int value_count,
9555 enum nk_draw_vertex_layout_format format)
9558 void *attribute = dst;
9560 NK_ASSERT(format < NK_FORMAT_COLOR_BEGIN);
9561 if (format >= NK_FORMAT_COLOR_BEGIN && format <= NK_FORMAT_COLOR_END)
return;
9562 for (value_index = 0; value_index < value_count; ++value_index) {
9564 default: NK_ASSERT(0 &&
"invalid vertex layout format");
break;
9565 case NK_FORMAT_SCHAR: {
9566 char value = (char)
NK_CLAMP((
float)NK_SCHAR_MIN, values[value_index], (float)NK_SCHAR_MAX);
9567 NK_MEMCPY(attribute, &value,
sizeof(value));
9568 attribute = (
void*)((
char*)attribute +
sizeof(char));
9570 case NK_FORMAT_SSHORT: {
9572 NK_MEMCPY(attribute, &value,
sizeof(value));
9573 attribute = (
void*)((
char*)attribute +
sizeof(value));
9575 case NK_FORMAT_SINT: {
9577 NK_MEMCPY(attribute, &value,
sizeof(value));
9578 attribute = (
void*)((
char*)attribute +
sizeof(
nk_int));
9580 case NK_FORMAT_UCHAR: {
9581 unsigned char value = (
unsigned char)
NK_CLAMP((
float)NK_UCHAR_MIN, values[value_index], (float)NK_UCHAR_MAX);
9582 NK_MEMCPY(attribute, &value,
sizeof(value));
9583 attribute = (
void*)((
char*)attribute +
sizeof(
unsigned char));
9585 case NK_FORMAT_USHORT: {
9587 NK_MEMCPY(attribute, &value,
sizeof(value));
9588 attribute = (
void*)((
char*)attribute +
sizeof(value));
9590 case NK_FORMAT_UINT: {
9592 NK_MEMCPY(attribute, &value,
sizeof(value));
9593 attribute = (
void*)((
char*)attribute +
sizeof(
nk_uint));
9595 case NK_FORMAT_FLOAT:
9596 NK_MEMCPY(attribute, &values[value_index],
sizeof(values[value_index]));
9597 attribute = (
void*)((
char*)attribute +
sizeof(float));
9599 case NK_FORMAT_DOUBLE: {
9600 double value = (double)values[value_index];
9601 NK_MEMCPY(attribute, &value,
sizeof(value));
9602 attribute = (
void*)((
char*)attribute +
sizeof(double));
9611 void *result = (
void*)((
char*)dst + config->
vertex_size);
9612 const struct nk_draw_vertex_layout_element *elem_iter = config->
vertex_layout;
9613 while (!nk_draw_vertex_layout_element_is_end_of_layout(elem_iter)) {
9614 void *address = (
void*)((
char*)dst + elem_iter->offset);
9615 switch (elem_iter->attribute) {
9616 case NK_VERTEX_ATTRIBUTE_COUNT:
9617 default: NK_ASSERT(0 &&
"wrong element attribute");
break;
9618 case NK_VERTEX_POSITION: nk_draw_vertex_element(address, &pos.
x, 2, elem_iter->format);
break;
9619 case NK_VERTEX_TEXCOORD: nk_draw_vertex_element(address, &uv.
x, 2, elem_iter->format);
break;
9620 case NK_VERTEX_COLOR: nk_draw_vertex_color(address, &color.
r, elem_iter->format);
break;
9627 nk_draw_list_stroke_poly_line(
struct nk_draw_list *list,
const struct nk_vec2 *points,
9628 const unsigned int points_count,
struct nk_color color,
enum nk_draw_list_stroke closed,
9636 if (!list || points_count < 2)
return;
9638 color.
a = (
nk_byte)((
float)color.
a * list->config.global_alpha);
9639 count = points_count;
9640 if (!closed) count = points_count-1;
9641 thick_line = thickness > 1.0f;
9643 #ifdef NK_INCLUDE_COMMAND_USERDATA
9644 nk_draw_list_push_userdata(list, list->userdata);
9647 color.
a = (
nk_byte)((
float)color.
a * list->config.global_alpha);
9654 const float AA_SIZE = 1.0f;
9661 nk_size index = list->vertex_count;
9663 const nk_size idx_count = (thick_line) ? (count * 18) : (count * 12);
9664 const nk_size vtx_count = (thick_line) ? (points_count * 4): (points_count *3);
9666 void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9667 nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9670 struct nk_vec2 *normals, *temp;
9671 if (!vtx || !ids)
return;
9676 size = pnt_size * ((thick_line) ? 5 : 3) * points_count;
9678 if (!normals)
return;
9679 temp = normals + points_count;
9682 vtx = (
void*)((
nk_byte*)list->vertices->memory.ptr + vertex_offset);
9685 for (i1 = 0; i1 < count; ++i1) {
9686 const nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
9693 len = nk_inv_sqrt(len);
9697 normals[i1].
x = diff.
y;
9698 normals[i1].
y = -diff.
x;
9702 normals[points_count-1] = normals[points_count-2];
9711 temp[(points_count-1) * 2 + 0] =
nk_vec2_add(points[points_count-1], d);
9712 temp[(points_count-1) * 2 + 1] =
nk_vec2_sub(points[points_count-1], d);
9717 for (i1 = 0; i1 < count; i1++) {
9720 nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
9721 nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 3);
9725 dmr2 = dm.x * dm.x + dm.y* dm.y;
9726 if (dmr2 > 0.000001f) {
9727 float scale = 1.0f/dmr2;
9728 scale =
NK_MIN(100.0f, scale);
9736 ids[0] = (nk_draw_index)(idx2 + 0); ids[1] = (nk_draw_index)(idx1+0);
9737 ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
9738 ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+0);
9739 ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
9740 ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
9741 ids[10]= (nk_draw_index)(idx2 + 0); ids[11]= (nk_draw_index)(idx2+1);
9747 for (i = 0; i < points_count; ++i) {
9748 const struct nk_vec2 uv = list->config.null.uv;
9749 vtx = nk_draw_vertex(vtx, &list->config, points[i], uv, col);
9750 vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+0], uv, col_trans);
9751 vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+1], uv, col_trans);
9755 const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f;
9765 d1 =
nk_vec2_muls(normals[points_count-1], half_inner_thickness + AA_SIZE);
9766 d2 =
nk_vec2_muls(normals[points_count-1], half_inner_thickness);
9768 temp[(points_count-1)*4+0] =
nk_vec2_add(points[points_count-1], d1);
9769 temp[(points_count-1)*4+1] =
nk_vec2_add(points[points_count-1], d2);
9770 temp[(points_count-1)*4+2] =
nk_vec2_sub(points[points_count-1], d2);
9771 temp[(points_count-1)*4+3] =
nk_vec2_sub(points[points_count-1], d1);
9776 for (i1 = 0; i1 < count; ++i1) {
9778 const nk_size i2 = ((i1+1) == points_count) ? 0: (i1 + 1);
9779 nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 4);
9783 float dmr2 = dm.
x * dm.
x + dm.
y* dm.
y;
9784 if (dmr2 > 0.000001f) {
9785 float scale = 1.0f/dmr2;
9786 scale =
NK_MIN(100.0f, scale);
9790 dm_out =
nk_vec2_muls(dm, ((half_inner_thickness) + AA_SIZE));
9798 ids[0] = (nk_draw_index)(idx2 + 1); ids[1] = (nk_draw_index)(idx1+1);
9799 ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
9800 ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+1);
9801 ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
9802 ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
9803 ids[10]= (nk_draw_index)(idx2 + 0); ids[11] = (nk_draw_index)(idx2+1);
9804 ids[12]= (nk_draw_index)(idx2 + 2); ids[13] = (nk_draw_index)(idx1+2);
9805 ids[14]= (nk_draw_index)(idx1 + 3); ids[15] = (nk_draw_index)(idx1+3);
9806 ids[16]= (nk_draw_index)(idx2 + 3); ids[17] = (nk_draw_index)(idx2+2);
9812 for (i = 0; i < points_count; ++i) {
9813 const struct nk_vec2 uv = list->config.null.uv;
9814 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+0], uv, col_trans);
9815 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+1], uv, col);
9816 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+2], uv, col);
9817 vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+3], uv, col_trans);
9825 nk_size idx = list->vertex_count;
9826 const nk_size idx_count = count * 6;
9827 const nk_size vtx_count = count * 4;
9828 void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9829 nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9830 if (!vtx || !ids)
return;
9832 for (i1 = 0; i1 < count; ++i1) {
9834 const struct nk_vec2 uv = list->config.null.uv;
9835 const nk_size i2 = ((i1+1) == points_count) ? 0 : i1 + 1;
9836 const struct nk_vec2 p1 = points[i1];
9837 const struct nk_vec2 p2 = points[i2];
9844 len = nk_inv_sqrt(len);
9849 dx = diff.
x * (thickness * 0.5f);
9850 dy = diff.
y * (thickness * 0.5f);
9852 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(p1.
x + dy, p1.
y - dx), uv, col);
9853 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(p2.
x + dy, p2.
y - dx), uv, col);
9854 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(p2.
x - dy, p2.
y + dx), uv, col);
9855 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(p1.
x - dy, p1.
y + dx), uv, col);
9857 ids[0] = (nk_draw_index)(idx+0); ids[1] = (nk_draw_index)(idx+1);
9858 ids[2] = (nk_draw_index)(idx+2); ids[3] = (nk_draw_index)(idx+0);
9859 ids[4] = (nk_draw_index)(idx+2); ids[5] = (nk_draw_index)(idx+3);
9867 nk_draw_list_fill_poly_convex(
struct nk_draw_list *list,
9868 const struct nk_vec2 *points,
const unsigned int points_count,
9877 if (!list || points_count < 3)
return;
9879 #ifdef NK_INCLUDE_COMMAND_USERDATA
9880 nk_draw_list_push_userdata(list, list->userdata);
9883 color.
a = (
nk_byte)((
float)color.
a * list->config.global_alpha);
9893 const float AA_SIZE = 1.0f;
9895 nk_size index = list->vertex_count;
9897 const nk_size idx_count = (points_count-2)*3 + points_count*6;
9898 const nk_size vtx_count = (points_count*2);
9900 void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9901 nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9905 unsigned int vtx_inner_idx = (
unsigned int)(index + 0);
9906 unsigned int vtx_outer_idx = (
unsigned int)(index + 1);
9907 if (!vtx || !ids)
return;
9912 size = pnt_size * points_count;
9914 if (!normals)
return;
9915 vtx = (
void*)((
nk_byte*)list->vertices->memory.ptr + vertex_offset);
9918 for (i = 2; i < points_count; i++) {
9919 ids[0] = (nk_draw_index)(vtx_inner_idx);
9920 ids[1] = (nk_draw_index)(vtx_inner_idx + ((i-1) << 1));
9921 ids[2] = (nk_draw_index)(vtx_inner_idx + (i << 1));
9926 for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
9927 struct nk_vec2 p0 = points[i0];
9928 struct nk_vec2 p1 = points[i1];
9934 len = nk_inv_sqrt(len);
9938 normals[i0].
x = diff.
y;
9939 normals[i0].
y = -diff.
x;
9943 for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
9944 const struct nk_vec2 uv = list->config.null.uv;
9945 struct nk_vec2 n0 = normals[i0];
9946 struct nk_vec2 n1 = normals[i1];
9948 float dmr2 = dm.
x*dm.
x + dm.
y*dm.
y;
9949 if (dmr2 > 0.000001f) {
9950 float scale = 1.0f / dmr2;
9951 scale =
NK_MIN(scale, 100.0f);
9957 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2_sub(points[i1], dm), uv, col);
9958 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2_add(points[i1], dm), uv, col_trans);
9961 ids[0] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
9962 ids[1] = (nk_draw_index)(vtx_inner_idx+(i0<<1));
9963 ids[2] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
9964 ids[3] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
9965 ids[4] = (nk_draw_index)(vtx_outer_idx+(i1<<1));
9966 ids[5] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
9973 nk_size index = list->vertex_count;
9974 const nk_size idx_count = (points_count-2)*3;
9975 const nk_size vtx_count = points_count;
9976 void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9977 nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9979 if (!vtx || !ids)
return;
9980 for (i = 0; i < vtx_count; ++i)
9981 vtx = nk_draw_vertex(vtx, &list->config, points[i], list->config.null.uv, col);
9982 for (i = 2; i < points_count; ++i) {
9983 ids[0] = (nk_draw_index)index;
9984 ids[1] = (nk_draw_index)(index+ i - 1);
9985 ids[2] = (nk_draw_index)(index+i);
9991 nk_draw_list_path_clear(
struct nk_draw_list *list)
9996 list->path_count = 0;
9997 list->path_offset = 0;
10000 nk_draw_list_path_line_to(
struct nk_draw_list *list,
struct nk_vec2 pos)
10003 struct nk_draw_command *cmd = 0;
10006 if (!list->cmd_count)
10007 nk_draw_list_add_clip(list, nk_null_rect);
10009 cmd = nk_draw_list_command_last(list);
10010 if (cmd && cmd->texture.ptr != list->config.null.texture.ptr)
10011 nk_draw_list_push_image(list, list->config.null.texture);
10013 points = nk_draw_list_alloc_path(list, 1);
10014 if (!points)
return;
10018 nk_draw_list_path_arc_to_fast(
struct nk_draw_list *list,
struct nk_vec2 center,
10019 float radius,
int a_min,
int a_max)
10024 if (a_min <= a_max) {
10025 for (a = a_min; a <= a_max; a++) {
10027 const float x = center.
x + c.
x * radius;
10028 const float y = center.
y + c.
y * radius;
10029 nk_draw_list_path_line_to(list,
nk_vec2(
x,
y));
10034 nk_draw_list_path_arc_to(
struct nk_draw_list *list,
struct nk_vec2 center,
10035 float radius,
float a_min,
float a_max,
unsigned int segments)
10037 unsigned int i = 0;
10040 if (radius == 0.0f)
return;
10060 {
const float d_angle = (a_max - a_min) / (
float)segments;
10061 const float sin_d = (float)NK_SIN(d_angle);
10062 const float cos_d = (float)NK_COS(d_angle);
10064 float cx = (float)NK_COS(a_min) * radius;
10065 float cy = (float)NK_SIN(a_min) * radius;
10066 for(i = 0; i <= segments; ++i) {
10067 float new_cx, new_cy;
10068 const float x = center.
x + cx;
10069 const float y = center.
y + cy;
10070 nk_draw_list_path_line_to(list,
nk_vec2(
x,
y));
10072 new_cx = cx * cos_d - cy * sin_d;
10073 new_cy = cy * cos_d + cx * sin_d;
10079 nk_draw_list_path_rect_to(
struct nk_draw_list *list,
struct nk_vec2 a,
10080 struct nk_vec2 b,
float rounding)
10086 r =
NK_MIN(r, ((b.
x-a.
x) < 0) ? -(b.
x-a.
x): (b.
x-a.
x));
10087 r =
NK_MIN(r, ((b.
y-a.
y) < 0) ? -(b.
y-a.
y): (b.
y-a.
y));
10090 nk_draw_list_path_line_to(list, a);
10091 nk_draw_list_path_line_to(list,
nk_vec2(b.
x,a.
y));
10092 nk_draw_list_path_line_to(list, b);
10093 nk_draw_list_path_line_to(list,
nk_vec2(a.
x,b.
y));
10095 nk_draw_list_path_arc_to_fast(list,
nk_vec2(a.
x + r, a.
y + r), r, 6, 9);
10096 nk_draw_list_path_arc_to_fast(list,
nk_vec2(b.
x - r, a.
y + r), r, 9, 12);
10097 nk_draw_list_path_arc_to_fast(list,
nk_vec2(b.
x - r, b.
y - r), r, 0, 3);
10098 nk_draw_list_path_arc_to_fast(list,
nk_vec2(a.
x + r, b.
y - r), r, 3, 6);
10102 nk_draw_list_path_curve_to(
struct nk_draw_list *list,
struct nk_vec2 p2,
10103 struct nk_vec2 p3,
struct nk_vec2 p4,
unsigned int num_segments)
10106 unsigned int i_step;
10110 NK_ASSERT(list->path_count);
10111 if (!list || !list->path_count)
return;
10112 num_segments =
NK_MAX(num_segments, 1);
10114 p1 = nk_draw_list_path_last(list);
10115 t_step = 1.0f/(float)num_segments;
10116 for (i_step = 1; i_step <= num_segments; ++i_step) {
10117 float t = t_step * (float)i_step;
10118 float u = 1.0f - t;
10120 float w2 = 3*u*u*t;
10121 float w3 = 3*u*t*t;
10122 float w4 = t * t *t;
10123 float x = w1 * p1.
x + w2 * p2.
x + w3 * p3.
x + w4 * p4.
x;
10124 float y = w1 * p1.
y + w2 * p2.
y + w3 * p3.
y + w4 * p4.
y;
10125 nk_draw_list_path_line_to(list,
nk_vec2(
x,
y));
10129 nk_draw_list_path_fill(
struct nk_draw_list *list,
struct nk_color color)
10135 nk_draw_list_fill_poly_convex(list, points, list->path_count, color, list->config.shape_AA);
10136 nk_draw_list_path_clear(list);
10139 nk_draw_list_path_stroke(
struct nk_draw_list *list,
struct nk_color color,
10140 enum nk_draw_list_stroke closed,
float thickness)
10146 nk_draw_list_stroke_poly_line(list, points, list->path_count, color,
10147 closed, thickness, list->config.line_AA);
10148 nk_draw_list_path_clear(list);
10151 nk_draw_list_stroke_line(
struct nk_draw_list *list,
struct nk_vec2 a,
10155 if (!list || !col.
a)
return;
10157 nk_draw_list_path_line_to(list, a);
10158 nk_draw_list_path_line_to(list, b);
10163 nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
10166 nk_draw_list_fill_rect(
struct nk_draw_list *list,
struct nk_rect rect,
10167 struct nk_color col,
float rounding)
10170 if (!list || !col.
a)
return;
10173 nk_draw_list_path_rect_to(list,
nk_vec2(rect.
x, rect.
y),
10174 nk_vec2(rect.
x + rect.
w, rect.
y + rect.
h), rounding);
10176 nk_draw_list_path_rect_to(list,
nk_vec2(rect.
x-0.5f, rect.
y-0.5f),
10177 nk_vec2(rect.
x + rect.
w, rect.
y + rect.
h), rounding);
10178 } nk_draw_list_path_fill(list, col);
10181 nk_draw_list_stroke_rect(
struct nk_draw_list *list,
struct nk_rect rect,
10182 struct nk_color col,
float rounding,
float thickness)
10185 if (!list || !col.
a)
return;
10187 nk_draw_list_path_rect_to(list,
nk_vec2(rect.
x, rect.
y),
10188 nk_vec2(rect.
x + rect.
w, rect.
y + rect.
h), rounding);
10190 nk_draw_list_path_rect_to(list,
nk_vec2(rect.
x-0.5f, rect.
y-0.5f),
10191 nk_vec2(rect.
x + rect.
w, rect.
y + rect.
h), rounding);
10192 } nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
10195 nk_draw_list_fill_rect_multi_color(
struct nk_draw_list *list,
struct nk_rect rect,
10201 struct nk_colorf col_right, col_bottom;
10202 nk_draw_index *idx;
10203 nk_draw_index index;
10213 nk_draw_list_push_image(list, list->config.null.texture);
10214 index = (nk_draw_index)list->vertex_count;
10215 vtx = nk_draw_list_alloc_vertices(list, 4);
10216 idx = nk_draw_list_alloc_elements(list, 6);
10217 if (!vtx || !idx)
return;
10219 idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
10220 idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
10221 idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
10223 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(rect.
x, rect.
y), list->config.null.uv, col_left);
10224 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(rect.
x + rect.
w, rect.
y), list->config.null.uv, col_top);
10225 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(rect.
x + rect.
w, rect.
y + rect.
h), list->config.null.uv, col_right);
10226 vtx = nk_draw_vertex(vtx, &list->config,
nk_vec2(rect.
x, rect.
y + rect.
h), list->config.null.uv, col_bottom);
10229 nk_draw_list_fill_triangle(
struct nk_draw_list *list,
struct nk_vec2 a,
10233 if (!list || !col.
a)
return;
10234 nk_draw_list_path_line_to(list,
a);
10235 nk_draw_list_path_line_to(list,
b);
10236 nk_draw_list_path_line_to(list, c);
10237 nk_draw_list_path_fill(list, col);
10240 nk_draw_list_stroke_triangle(
struct nk_draw_list *list,
struct nk_vec2 a,
10244 if (!list || !col.
a)
return;
10245 nk_draw_list_path_line_to(list,
a);
10246 nk_draw_list_path_line_to(list,
b);
10247 nk_draw_list_path_line_to(list, c);
10248 nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
10251 nk_draw_list_fill_circle(
struct nk_draw_list *list,
struct nk_vec2 center,
10252 float radius,
struct nk_color col,
unsigned int segs)
10256 if (!list || !col.
a)
return;
10257 a_max =
NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
10258 nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
10259 nk_draw_list_path_fill(list, col);
10262 nk_draw_list_stroke_circle(
struct nk_draw_list *list,
struct nk_vec2 center,
10263 float radius,
struct nk_color col,
unsigned int segs,
float thickness)
10267 if (!list || !col.
a)
return;
10268 a_max =
NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
10269 nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
10270 nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
10273 nk_draw_list_stroke_curve(
struct nk_draw_list *list,
struct nk_vec2 p0,
10275 struct nk_color col,
unsigned int segments,
float thickness)
10278 if (!list || !col.
a)
return;
10279 nk_draw_list_path_line_to(list, p0);
10280 nk_draw_list_path_curve_to(list, cp0, cp1, p1, segments);
10281 nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
10284 nk_draw_list_push_rect_uv(
struct nk_draw_list *list,
struct nk_vec2 a,
10295 nk_draw_index *idx;
10296 nk_draw_index index;
10306 index = (nk_draw_index)list->vertex_count;
10307 vtx = nk_draw_list_alloc_vertices(list, 4);
10308 idx = nk_draw_list_alloc_elements(list, 6);
10309 if (!vtx || !idx)
return;
10311 idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
10312 idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
10313 idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
10315 vtx = nk_draw_vertex(vtx, &list->config,
a, uva, col);
10316 vtx = nk_draw_vertex(vtx, &list->config,
b, uvb, col);
10317 vtx = nk_draw_vertex(vtx, &list->config, c, uvc, col);
10318 vtx = nk_draw_vertex(vtx, &list->config, d, uvd, col);
10321 nk_draw_list_add_image(
struct nk_draw_list *list,
struct nk_image texture,
10327 nk_draw_list_push_image(list, texture.
handle);
10331 uv[0].
x = (float)texture.
region[0]/(
float)texture.
w;
10332 uv[0].
y = (float)texture.
region[1]/(
float)texture.
h;
10333 uv[1].
x = (float)(texture.
region[0] + texture.
region[2])/(float)texture.
w;
10334 uv[1].y = (
float)(texture.
region[1] + texture.
region[3])/(
float)texture.
h;
10335 nk_draw_list_push_rect_uv(list,
nk_vec2(rect.
x, rect.
y),
10336 nk_vec2(rect.
x + rect.
w, rect.
y + rect.
h), uv[0], uv[1], color);
10337 }
else nk_draw_list_push_rect_uv(list,
nk_vec2(rect.
x, rect.
y),
10342 nk_draw_list_add_text(
struct nk_draw_list *list,
const struct nk_user_font *font,
10343 struct nk_rect rect,
const char *text,
int len,
float font_height,
10351 int next_glyph_len = 0;
10352 struct nk_user_font_glyph g;
10355 if (!list || !len || !text)
return;
10357 list->clip_rect.x, list->clip_rect.y, list->clip_rect.w, list->clip_rect.h))
return;
10359 nk_draw_list_push_image(list, font->texture);
10362 if (!glyph_len)
return;
10365 fg.
a = (
nk_byte)((
float)fg.
a * list->config.global_alpha);
10366 while (text_len < len && glyph_len) {
10367 float gx, gy, gh, gw;
10368 float char_width = 0;
10372 next_glyph_len =
nk_utf_decode(text + text_len + glyph_len, &next, (
int)len - text_len);
10373 font->query(font->
userdata, font_height, &g, unicode,
10377 gx = x + g.offset.x;
10378 gy = rect.
y + g.offset.y;
10379 gw = g.width; gh = g.height;
10380 char_width = g.xadvance;
10381 nk_draw_list_push_rect_uv(list,
nk_vec2(gx,gy),
nk_vec2(gx + gw, gy+ gh),
10382 g.uv[0], g.uv[1], fg);
10385 text_len += glyph_len;
10387 glyph_len = next_glyph_len;
10400 NK_ASSERT(vertices);
10401 NK_ASSERT(elements);
10405 if (!
ctx || !cmds || !vertices || !elements || !config || !config->
vertex_layout)
10408 nk_draw_list_setup(&
ctx->draw_list, config, cmds, vertices, elements,
10412 #ifdef NK_INCLUDE_COMMAND_USERDATA
10413 ctx->draw_list.userdata = cmd->userdata;
10415 switch (cmd->
type) {
10419 nk_draw_list_add_clip(&
ctx->draw_list,
nk_rect(s->
x, s->
y, s->
w, s->
h));
10435 nk_draw_list_stroke_rect(&
ctx->draw_list,
nk_rect(r->
x, r->
y, r->
w, r->
h),
10440 nk_draw_list_fill_rect(&
ctx->draw_list,
nk_rect(r->
x, r->
y, r->
w, r->
h),
10445 nk_draw_list_fill_rect_multi_color(&
ctx->draw_list,
nk_rect(r->
x, r->
y, r->
w, r->
h),
10450 nk_draw_list_stroke_circle(&
ctx->draw_list,
nk_vec2((
float)c->
x + (
float)c->
w/2,
10451 (
float)c->
y + (
float)c->
h/2), (
float)c->
w/2, c->
color,
10456 nk_draw_list_fill_circle(&
ctx->draw_list,
nk_vec2((
float)c->
x + (
float)c->
w/2,
10457 (
float)c->
y + (
float)c->
h/2), (
float)c->
w/2, c->
color,
10462 nk_draw_list_path_line_to(&
ctx->draw_list,
nk_vec2(c->
cx, c->
cy));
10463 nk_draw_list_path_arc_to(&
ctx->draw_list,
nk_vec2(c->
cx, c->
cy), c->
r,
10469 nk_draw_list_path_line_to(&
ctx->draw_list,
nk_vec2(c->
cx, c->
cy));
10470 nk_draw_list_path_arc_to(&
ctx->draw_list,
nk_vec2(c->
cx, c->
cy), c->
r,
10472 nk_draw_list_path_fill(&
ctx->draw_list, c->
color);
10476 nk_draw_list_stroke_triangle(&
ctx->draw_list,
nk_vec2(t->
a.
x, t->
a.
y),
10482 nk_draw_list_fill_triangle(&
ctx->draw_list,
nk_vec2(t->
a.
x, t->
a.
y),
10490 nk_draw_list_path_line_to(&
ctx->draw_list, pnt);
10499 nk_draw_list_path_line_to(&
ctx->draw_list, pnt);
10501 nk_draw_list_path_fill(&
ctx->draw_list, p->
color);
10508 nk_draw_list_path_line_to(&
ctx->draw_list, pnt);
10533 NK_API const struct nk_draw_command*
10537 return nk__draw_list_begin(&
ctx->draw_list, buffer);
10539 NK_API const struct nk_draw_command*
10542 return nk__draw_list_end(&
ctx->draw_list, buffer);
10544 NK_API const struct nk_draw_command*
10545 nk__draw_next(
const struct nk_draw_command *cmd,
10548 return nk__draw_list_next(cmd, buffer, &
ctx->draw_list);
10556 #ifdef NK_INCLUDE_FONT_BAKING
10564 #define NK_RP__MAXVAL 0xffff
10565 typedef unsigned short nk_rp_coord;
10567 struct nk_rp_rect {
10578 struct nk_rp_node {
10580 struct nk_rp_node *next;
10583 struct nk_rp_context {
10590 struct nk_rp_node *active_head;
10591 struct nk_rp_node *free_head;
10592 struct nk_rp_node extra[2];
10596 struct nk_rp__findresult {
10598 struct nk_rp_node **prev_link;
10601 enum NK_RP_HEURISTIC {
10602 NK_RP_HEURISTIC_Skyline_default=0,
10603 NK_RP_HEURISTIC_Skyline_BL_sortHeight = NK_RP_HEURISTIC_Skyline_default,
10604 NK_RP_HEURISTIC_Skyline_BF_sortHeight
10606 enum NK_RP_INIT_STATE{NK_RP__INIT_skyline = 1};
10609 nk_rp_setup_allow_out_of_mem(
struct nk_rp_context *context,
int allow_out_of_mem)
10611 if (allow_out_of_mem)
10616 context->align = 1;
10624 context->align = (context->width + context->num_nodes-1) / context->num_nodes;
10628 nk_rp_init_target(
struct nk_rp_context *context,
int width,
int height,
10629 struct nk_rp_node *nodes,
int num_nodes)
10632 #ifndef STBRP_LARGE_RECTS
10633 NK_ASSERT(width <= 0xffff && height <= 0xffff);
10636 for (i=0; i < num_nodes-1; ++i)
10637 nodes[i].next = &nodes[i+1];
10639 context->init_mode = NK_RP__INIT_skyline;
10640 context->heuristic = NK_RP_HEURISTIC_Skyline_default;
10641 context->free_head = &nodes[0];
10642 context->active_head = &context->extra[0];
10643 context->width = width;
10644 context->height = height;
10645 context->num_nodes = num_nodes;
10646 nk_rp_setup_allow_out_of_mem(context, 0);
10649 context->extra[0].x = 0;
10650 context->extra[0].y = 0;
10651 context->extra[0].next = &context->extra[1];
10652 context->extra[1].x = (nk_rp_coord) width;
10653 context->extra[1].y = 65535;
10654 context->extra[1].next = 0;
10658 nk_rp__skyline_find_min_y(
struct nk_rp_context *c,
struct nk_rp_node *first,
10659 int x0,
int width,
int *pwaste)
10661 struct nk_rp_node *node = first;
10662 int x1 = x0 + width;
10663 int min_y, visited_width, waste_area;
10664 NK_ASSERT(first->x <= x0);
10667 NK_ASSERT(node->next->x > x0);
10669 NK_ASSERT(node->x <= x0);
10674 while (node->x < x1)
10676 if (node->y > min_y) {
10680 waste_area += visited_width * (node->y - min_y);
10684 visited_width += node->next->x - x0;
10686 visited_width += node->next->x - node->x;
10689 int under_width = node->next->x - node->x;
10690 if (under_width + visited_width > width)
10691 under_width = width - visited_width;
10692 waste_area += under_width * (min_y - node->y);
10693 visited_width += under_width;
10697 *pwaste = waste_area;
10701 nk_rp__skyline_find_best_pos(struct nk_rp_context *c,
int width,
int height)
10703 int best_waste = (1<<30), best_x, best_y = (1 << 30);
10704 struct nk_rp__findresult fr;
10705 struct nk_rp_node **prev, *node, *tail, **best = 0;
10708 width = (width + c->align - 1);
10709 width -= width % c->align;
10710 NK_ASSERT(width % c->align == 0);
10712 node = c->active_head;
10713 prev = &c->active_head;
10714 while (node->x + width <= c->width) {
10716 y = nk_rp__skyline_find_min_y(c, node, node->x, width, &waste);
10718 if (c->heuristic == NK_RP_HEURISTIC_Skyline_BL_sortHeight) {
10726 if (y + height <= c->height) {
10728 if (y < best_y || (y == best_y && waste < best_waste)) {
10730 best_waste = waste;
10735 prev = &node->next;
10738 best_x = (best == 0) ? 0 : (*best)->x;
10756 if (c->heuristic == NK_RP_HEURISTIC_Skyline_BF_sortHeight)
10758 tail = c->active_head;
10759 node = c->active_head;
10760 prev = &c->active_head;
10762 while (tail->x < width)
10766 int xpos = tail->x - width;
10768 NK_ASSERT(xpos >= 0);
10770 while (node->next->x <= xpos) {
10771 prev = &node->next;
10774 NK_ASSERT(node->next->x > xpos && node->x <= xpos);
10775 y = nk_rp__skyline_find_min_y(c, node, xpos, width, &waste);
10776 if (y + height < c->height) {
10778 if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
10780 NK_ASSERT(y <= best_y);
10782 best_waste = waste;
10790 fr.prev_link = best;
10796 nk_rp__skyline_pack_rectangle(struct nk_rp_context *context,
int width,
int height)
10799 struct nk_rp__findresult res = nk_rp__skyline_find_best_pos(context, width, height);
10800 struct nk_rp_node *node, *cur;
10806 if (res.prev_link == 0 || res.y + height > context->height || context->free_head == 0) {
10812 node = context->free_head;
10813 node->x = (nk_rp_coord) res.x;
10814 node->y = (nk_rp_coord) (res.y + height);
10816 context->free_head = node->next;
10821 cur = *res.prev_link;
10822 if (cur->x < res.x) {
10824 struct nk_rp_node *next = cur->next;
10828 *res.prev_link = node;
10833 while (cur->next && cur->next->x <= res.x + width) {
10834 struct nk_rp_node *next = cur->next;
10836 cur->next = context->free_head;
10837 context->free_head = cur;
10843 if (cur->x < res.x + width)
10844 cur->x = (nk_rp_coord) (res.x + width);
10848 nk_rect_height_compare(
const void *a,
const void *b)
10850 const struct nk_rp_rect *p = (
const struct nk_rp_rect *) a;
10851 const struct nk_rp_rect *q = (
const struct nk_rp_rect *) b;
10856 return (p->w > q->w) ? -1 : (p->w < q->w);
10859 nk_rect_original_order(
const void *a,
const void *b)
10861 const struct nk_rp_rect *p = (
const struct nk_rp_rect *) a;
10862 const struct nk_rp_rect *q = (
const struct nk_rp_rect *) b;
10863 return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
10866 nk_rp_qsort(
struct nk_rp_rect *array,
unsigned int len,
int(*cmp)(
const void*,
const void*))
10869 #define NK_MAX_SORT_STACK 64
10870 unsigned right, left = 0, stack[NK_MAX_SORT_STACK], pos = 0;
10871 unsigned seed = len/2 * 69069+1;
10873 for (; left+1 < len; len++) {
10874 struct nk_rp_rect pivot, tmp;
10875 if (pos == NK_MAX_SORT_STACK) len = stack[pos = 0];
10876 pivot = array[left+seed%(len-left)];
10877 seed = seed * 69069 + 1;
10878 stack[pos++] = len;
10879 for (right = left-1;;) {
10880 while (cmp(&array[++right], &pivot) < 0);
10881 while (cmp(&pivot, &array[--len]) < 0);
10882 if (right >= len)
break;
10883 tmp = array[right];
10884 array[right] = array[len];
10888 if (pos == 0)
break;
10890 len = stack[--pos];
10892 #undef NK_MAX_SORT_STACK
10895 nk_rp_pack_rects(
struct nk_rp_context *context,
struct nk_rp_rect *rects,
int num_rects)
10899 for (i=0; i < num_rects; ++i) {
10900 rects[i].was_packed = i;
10904 nk_rp_qsort(rects, (
unsigned)num_rects, nk_rect_height_compare);
10906 for (i=0; i < num_rects; ++i) {
10907 struct nk_rp__findresult fr = nk_rp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
10908 if (fr.prev_link) {
10909 rects[i].x = (nk_rp_coord) fr.x;
10910 rects[i].y = (nk_rp_coord) fr.y;
10912 rects[i].x = rects[i].y = NK_RP__MAXVAL;
10917 nk_rp_qsort(rects, (
unsigned)num_rects, nk_rect_original_order);
10920 for (i=0; i < num_rects; ++i)
10921 rects[i].was_packed = !(rects[i].x == NK_RP__MAXVAL && rects[i].y == NK_RP__MAXVAL);
10932 #define NK_TT_MAX_OVERSAMPLE 8
10933 #define NK_TT__OVER_MASK (NK_TT_MAX_OVERSAMPLE-1)
10935 struct nk_tt_bakedchar {
10936 unsigned short x0,y0,x1,y1;
10938 float xoff,yoff,xadvance;
10941 struct nk_tt_aligned_quad{
10946 struct nk_tt_packedchar {
10947 unsigned short x0,y0,x1,y1;
10949 float xoff,yoff,xadvance;
10953 struct nk_tt_pack_range {
10955 int first_unicode_codepoint_in_range;
10957 int *array_of_unicode_codepoints;
10960 struct nk_tt_packedchar *chardata_for_range;
10961 unsigned char h_oversample, v_oversample;
10965 struct nk_tt_pack_context {
10969 int stride_in_bytes;
10971 unsigned int h_oversample, v_oversample;
10972 unsigned char *pixels;
10976 struct nk_tt_fontinfo {
10977 const unsigned char* data;
10980 int loca,head,glyf,hhea,hmtx,kern;
10982 int indexToLocFormat;
10991 struct nk_tt_vertex {
10993 unsigned char type,padding;
10996 struct nk_tt__bitmap{
10998 unsigned char *pixels;
11001 struct nk_tt__hheap_chunk {
11002 struct nk_tt__hheap_chunk *next;
11004 struct nk_tt__hheap {
11006 struct nk_tt__hheap_chunk *head;
11008 int num_remaining_in_head_chunk;
11011 struct nk_tt__edge {
11012 float x0,y0, x1,y1;
11016 struct nk_tt__active_edge {
11017 struct nk_tt__active_edge *next;
11023 struct nk_tt__point {
float x,y;};
11025 #define NK_TT_MACSTYLE_DONTCARE 0
11026 #define NK_TT_MACSTYLE_BOLD 1
11027 #define NK_TT_MACSTYLE_ITALIC 2
11028 #define NK_TT_MACSTYLE_UNDERSCORE 4
11029 #define NK_TT_MACSTYLE_NONE 8
11033 NK_TT_PLATFORM_ID_UNICODE =0,
11034 NK_TT_PLATFORM_ID_MAC =1,
11035 NK_TT_PLATFORM_ID_ISO =2,
11036 NK_TT_PLATFORM_ID_MICROSOFT =3
11040 NK_TT_UNICODE_EID_UNICODE_1_0 =0,
11041 NK_TT_UNICODE_EID_UNICODE_1_1 =1,
11042 NK_TT_UNICODE_EID_ISO_10646 =2,
11043 NK_TT_UNICODE_EID_UNICODE_2_0_BMP=3,
11044 NK_TT_UNICODE_EID_UNICODE_2_0_FULL=4
11048 NK_TT_MS_EID_SYMBOL =0,
11049 NK_TT_MS_EID_UNICODE_BMP =1,
11050 NK_TT_MS_EID_SHIFTJIS =2,
11051 NK_TT_MS_EID_UNICODE_FULL =10
11055 NK_TT_MAC_EID_ROMAN =0, NK_TT_MAC_EID_ARABIC =4,
11056 NK_TT_MAC_EID_JAPANESE =1, NK_TT_MAC_EID_HEBREW =5,
11057 NK_TT_MAC_EID_CHINESE_TRAD =2, NK_TT_MAC_EID_GREEK =6,
11058 NK_TT_MAC_EID_KOREAN =3, NK_TT_MAC_EID_RUSSIAN =7
11063 NK_TT_MS_LANG_ENGLISH =0x0409, NK_TT_MS_LANG_ITALIAN =0x0410,
11064 NK_TT_MS_LANG_CHINESE =0x0804, NK_TT_MS_LANG_JAPANESE =0x0411,
11065 NK_TT_MS_LANG_DUTCH =0x0413, NK_TT_MS_LANG_KOREAN =0x0412,
11066 NK_TT_MS_LANG_FRENCH =0x040c, NK_TT_MS_LANG_RUSSIAN =0x0419,
11067 NK_TT_MS_LANG_GERMAN =0x0407, NK_TT_MS_LANG_SPANISH =0x0409,
11068 NK_TT_MS_LANG_HEBREW =0x040d, NK_TT_MS_LANG_SWEDISH =0x041D
11072 NK_TT_MAC_LANG_ENGLISH =0 , NK_TT_MAC_LANG_JAPANESE =11,
11073 NK_TT_MAC_LANG_ARABIC =12, NK_TT_MAC_LANG_KOREAN =23,
11074 NK_TT_MAC_LANG_DUTCH =4 , NK_TT_MAC_LANG_RUSSIAN =32,
11075 NK_TT_MAC_LANG_FRENCH =1 , NK_TT_MAC_LANG_SPANISH =6 ,
11076 NK_TT_MAC_LANG_GERMAN =2 , NK_TT_MAC_LANG_SWEDISH =5 ,
11077 NK_TT_MAC_LANG_HEBREW =10, NK_TT_MAC_LANG_CHINESE_SIMPLIFIED =33,
11078 NK_TT_MAC_LANG_ITALIAN =3 , NK_TT_MAC_LANG_CHINESE_TRAD =19
11081 #define nk_ttBYTE(p) (* (const nk_byte *) (p))
11082 #define nk_ttCHAR(p) (* (const char *) (p))
11084 #if defined(NK_BIGENDIAN) && !defined(NK_ALLOW_UNALIGNED_TRUETYPE)
11085 #define nk_ttUSHORT(p) (* (nk_ushort *) (p))
11086 #define nk_ttSHORT(p) (* (nk_short *) (p))
11087 #define nk_ttULONG(p) (* (nk_uint *) (p))
11088 #define nk_ttLONG(p) (* (nk_int *) (p))
11092 static nk_uint nk_ttULONG(
const nk_byte *p) {
return (
nk_uint)((p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]); }
11095 #define nk_tt_tag4(p,c0,c1,c2,c3)\
11096 ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
11097 #define nk_tt_tag(p,str) nk_tt_tag4(p,str[0],str[1],str[2],str[3])
11100 int glyph_index,
struct nk_tt_vertex **pvertices);
11103 nk_tt__find_table(
const nk_byte *data,
nk_uint fontstart,
const char *tag)
11106 nk_int num_tables = nk_ttUSHORT(data+fontstart+4);
11107 nk_uint tabledir = fontstart + 12;
11109 for (i = 0; i < num_tables; ++i) {
11111 if (nk_tt_tag(data+loc+0, tag))
11112 return nk_ttULONG(data+loc+8);
11117 nk_tt_InitFont(
struct nk_tt_fontinfo *info,
const unsigned char *data2,
int fontstart)
11124 info->fontstart = fontstart;
11126 cmap = nk_tt__find_table(data, (
nk_uint)fontstart,
"cmap");
11127 info->loca = (int)nk_tt__find_table(data, (
nk_uint)fontstart,
"loca");
11128 info->head = (int)nk_tt__find_table(data, (
nk_uint)fontstart,
"head");
11129 info->glyf = (int)nk_tt__find_table(data, (
nk_uint)fontstart,
"glyf");
11130 info->hhea = (int)nk_tt__find_table(data, (
nk_uint)fontstart,
"hhea");
11131 info->hmtx = (int)nk_tt__find_table(data, (
nk_uint)fontstart,
"hmtx");
11132 info->kern = (int)nk_tt__find_table(data, (
nk_uint)fontstart,
"kern");
11133 if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx)
11136 t = nk_tt__find_table(data, (
nk_uint)fontstart,
"maxp");
11137 if (t) info->numGlyphs = nk_ttUSHORT(data+t+4);
11138 else info->numGlyphs = 0xffff;
11143 numTables = nk_ttUSHORT(data + cmap + 2);
11144 info->index_map = 0;
11145 for (i=0; i < numTables; ++i)
11149 switch(nk_ttUSHORT(data+encoding_record)) {
11150 case NK_TT_PLATFORM_ID_MICROSOFT:
11151 switch (nk_ttUSHORT(data+encoding_record+2)) {
11152 case NK_TT_MS_EID_UNICODE_BMP:
11153 case NK_TT_MS_EID_UNICODE_FULL:
11155 info->index_map = (int)(cmap + nk_ttULONG(data+encoding_record+4));
11159 case NK_TT_PLATFORM_ID_UNICODE:
11162 info->index_map = (int)(cmap + nk_ttULONG(data+encoding_record+4));
11167 if (info->index_map == 0)
11169 info->indexToLocFormat = nk_ttUSHORT(data+info->head + 50);
11173 nk_tt_FindGlyphIndex(
const struct nk_tt_fontinfo *info,
int unicode_codepoint)
11175 const nk_byte *data = info->data;
11178 nk_ushort format = nk_ttUSHORT(data + index_map + 0);
11180 nk_int bytes = nk_ttUSHORT(data + index_map + 2);
11181 if (unicode_codepoint < bytes-6)
11182 return nk_ttBYTE(data + index_map + 6 + unicode_codepoint);
11184 }
else if (format == 6) {
11185 nk_uint first = nk_ttUSHORT(data + index_map + 6);
11186 nk_uint count = nk_ttUSHORT(data + index_map + 8);
11187 if ((
nk_uint) unicode_codepoint >= first && (
nk_uint) unicode_codepoint < first+count)
11188 return nk_ttUSHORT(data + index_map + 10 + (unicode_codepoint - (
int)first)*2);
11190 }
else if (format == 2) {
11193 }
else if (format == 4) {
11194 nk_ushort segcount = nk_ttUSHORT(data+index_map+6) >> 1;
11195 nk_ushort searchRange = nk_ttUSHORT(data+index_map+8) >> 1;
11196 nk_ushort entrySelector = nk_ttUSHORT(data+index_map+10);
11197 nk_ushort rangeShift = nk_ttUSHORT(data+index_map+12) >> 1;
11200 nk_uint endCount = index_map + 14;
11203 if (unicode_codepoint > 0xffff)
11208 if (unicode_codepoint >= nk_ttUSHORT(data + search + rangeShift*2))
11209 search += (
nk_uint)(rangeShift*2);
11213 while (entrySelector) {
11216 end = nk_ttUSHORT(data + search + searchRange*2);
11217 if (unicode_codepoint > end)
11218 search += (
nk_uint)(searchRange*2);
11227 NK_ASSERT(unicode_codepoint <= nk_ttUSHORT(data + endCount + 2*item));
11228 start = nk_ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
11229 if (unicode_codepoint < start)
11232 offset = nk_ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
11234 return (
nk_ushort) (unicode_codepoint + nk_ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));
11236 return nk_ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
11238 }
else if (format == 12 || format == 13) {
11239 nk_uint ngroups = nk_ttULONG(data+index_map+12);
11241 low = 0; high = (
nk_int)ngroups;
11243 while (low < high) {
11244 nk_int mid = low + ((high-low) >> 1);
11245 nk_uint start_char = nk_ttULONG(data+index_map+16+mid*12);
11246 nk_uint end_char = nk_ttULONG(data+index_map+16+mid*12+4);
11247 if ((
nk_uint) unicode_codepoint < start_char)
11249 else if ((
nk_uint) unicode_codepoint > end_char)
11252 nk_uint start_glyph = nk_ttULONG(data+index_map+16+mid*12+8);
11254 return (
int)start_glyph + (int)unicode_codepoint - (
int)start_char;
11256 return (
int)start_glyph;
11275 nk_tt__GetGlyfOffset(
const struct nk_tt_fontinfo *info,
int glyph_index)
11278 if (glyph_index >= info->numGlyphs)
return -1;
11279 if (info->indexToLocFormat >= 2)
return -1;
11281 if (info->indexToLocFormat == 0) {
11282 g1 = info->glyf + nk_ttUSHORT(info->data + info->loca + glyph_index * 2) * 2;
11283 g2 = info->glyf + nk_ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2;
11285 g1 = info->glyf + (int)nk_ttULONG (info->data + info->loca + glyph_index * 4);
11286 g2 = info->glyf + (int)nk_ttULONG (info->data + info->loca + glyph_index * 4 + 4);
11288 return g1==g2 ? -1 : g1;
11291 nk_tt_GetGlyphBox(
const struct nk_tt_fontinfo *info,
int glyph_index,
11292 int *x0,
int *y0,
int *x1,
int *y1)
11294 int g = nk_tt__GetGlyfOffset(info, glyph_index);
11295 if (g < 0)
return 0;
11297 if (x0) *x0 = nk_ttSHORT(info->data + g + 2);
11298 if (y0) *y0 = nk_ttSHORT(info->data + g + 4);
11299 if (x1) *x1 = nk_ttSHORT(info->data + g + 6);
11300 if (y1) *y1 = nk_ttSHORT(info->data + g + 8);
11304 nk_tt__close_shape(
struct nk_tt_vertex *vertices,
int num_vertices,
int was_off,
11309 nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy);
11310 nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, sx,sy,scx,scy);
11313 nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve,sx,sy,cx,cy);
11315 nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vline,sx,sy,0,0);
11317 return num_vertices;
11320 nk_tt_GetGlyphShape(
const struct nk_tt_fontinfo *info,
struct nk_allocator *alloc,
11321 int glyph_index,
struct nk_tt_vertex **pvertices)
11324 const nk_byte *endPtsOfContours;
11325 const nk_byte *data = info->data;
11326 struct nk_tt_vertex *vertices=0;
11327 int num_vertices=0;
11328 int g = nk_tt__GetGlyfOffset(info, glyph_index);
11331 if (g < 0)
return 0;
11332 numberOfContours = nk_ttSHORT(data + g);
11333 if (numberOfContours > 0) {
11335 nk_int ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0;
11336 nk_int x,y,cx,cy,sx,sy, scx,scy;
11338 endPtsOfContours = (data + g + 10);
11339 ins = nk_ttUSHORT(data + g + 10 + numberOfContours * 2);
11340 points = data + g + 10 + numberOfContours * 2 + 2 + ins;
11342 n = 1+nk_ttUSHORT(endPtsOfContours + numberOfContours*2-2);
11343 m = n + 2*numberOfContours;
11344 vertices = (
struct nk_tt_vertex *)alloc->
alloc(alloc->
userdata, 0, (
nk_size)m *
sizeof(vertices[0]));
11357 for (i=0; i < n; ++i) {
11358 if (flagcount == 0) {
11361 flagcount = *points++;
11362 }
else --flagcount;
11363 vertices[off+i].type = flags;
11368 for (i=0; i < n; ++i) {
11369 flags = vertices[off+i].type;
11372 x += (flags & 16) ? dx : -dx;
11374 if (!(flags & 16)) {
11375 x = x + (
nk_short) (points[0]*256 + points[1]);
11384 for (i=0; i < n; ++i) {
11385 flags = vertices[off+i].type;
11388 y += (flags & 32) ? dy : -dy;
11390 if (!(flags & 32)) {
11391 y = y + (
nk_short) (points[0]*256 + points[1]);
11400 sx = sy = cx = cy = scx = scy = 0;
11401 for (i=0; i < n; ++i)
11403 flags = vertices[off+i].type;
11407 if (next_move == i) {
11409 num_vertices = nk_tt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
11412 start_off = !(flags & 1);
11418 if (!(vertices[off+i+1].type & 1)) {
11420 sx = (x + (
nk_int) vertices[off+i+1].x) >> 1;
11421 sy = (y + (
nk_int) vertices[off+i+1].y) >> 1;
11424 sx = (
nk_int) vertices[off+i+1].x;
11425 sy = (
nk_int) vertices[off+i+1].y;
11432 nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vmove,sx,sy,0,0);
11434 next_move = 1 + nk_ttUSHORT(endPtsOfContours+j*2);
11440 nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy);
11446 nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, x,y, cx, cy);
11447 else nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vline, x,y,0,0);
11452 num_vertices = nk_tt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
11453 }
else if (numberOfContours == -1) {
11456 const nk_byte *comp = data + g + 10;
11463 int comp_num_verts = 0, i;
11464 struct nk_tt_vertex *comp_verts = 0, *tmp = 0;
11465 float mtx[6] = {1,0,0,1,0,0}, m, n;
11467 flags = (
nk_ushort)nk_ttSHORT(comp); comp+=2;
11468 gidx = (
nk_ushort)nk_ttSHORT(comp); comp+=2;
11472 mtx[4] = nk_ttSHORT(comp); comp+=2;
11473 mtx[5] = nk_ttSHORT(comp); comp+=2;
11475 mtx[4] = nk_ttCHAR(comp); comp+=1;
11476 mtx[5] = nk_ttCHAR(comp); comp+=1;
11482 if (flags & (1<<3)) {
11483 mtx[0] = mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11484 mtx[1] = mtx[2] = 0;
11485 }
else if (flags & (1<<6)) {
11486 mtx[0] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11487 mtx[1] = mtx[2] = 0;
11488 mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11489 }
else if (flags & (1<<7)) {
11490 mtx[0] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11491 mtx[1] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11492 mtx[2] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11493 mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11497 m = (float) NK_SQRT(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
11498 n = (float) NK_SQRT(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
11501 comp_num_verts = nk_tt_GetGlyphShape(info, alloc, gidx, &comp_verts);
11502 if (comp_num_verts > 0)
11505 for (i = 0; i < comp_num_verts; ++i) {
11506 struct nk_tt_vertex* v = &comp_verts[i];
11509 v->x = (short)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
11510 v->y = (short)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
11512 v->cx = (short)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
11513 v->cy = (short)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
11516 tmp = (
struct nk_tt_vertex*)alloc->
alloc(alloc->
userdata, 0,
11517 (
nk_size)(num_vertices+comp_num_verts)*
sizeof(
struct nk_tt_vertex));
11520 if (comp_verts) alloc->
free(alloc->
userdata, comp_verts);
11523 if (num_vertices > 0) NK_MEMCPY(tmp, vertices, (
nk_size)num_vertices*
sizeof(
struct nk_tt_vertex));
11524 NK_MEMCPY(tmp+num_vertices, comp_verts, (
nk_size)comp_num_verts*
sizeof(
struct nk_tt_vertex));
11528 num_vertices += comp_num_verts;
11531 more = flags & (1<<5);
11533 }
else if (numberOfContours < 0) {
11539 *pvertices = vertices;
11540 return num_vertices;
11543 nk_tt_GetGlyphHMetrics(
const struct nk_tt_fontinfo *info,
int glyph_index,
11544 int *advanceWidth,
int *leftSideBearing)
11546 nk_ushort numOfLongHorMetrics = nk_ttUSHORT(info->data+info->hhea + 34);
11547 if (glyph_index < numOfLongHorMetrics) {
11549 *advanceWidth = nk_ttSHORT(info->data + info->hmtx + 4*glyph_index);
11550 if (leftSideBearing)
11551 *leftSideBearing = nk_ttSHORT(info->data + info->hmtx + 4*glyph_index + 2);
11554 *advanceWidth = nk_ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1));
11555 if (leftSideBearing)
11556 *leftSideBearing = nk_ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics));
11560 nk_tt_GetFontVMetrics(
const struct nk_tt_fontinfo *info,
11561 int *ascent,
int *descent,
int *lineGap)
11563 if (ascent ) *ascent = nk_ttSHORT(info->data+info->hhea + 4);
11564 if (descent) *descent = nk_ttSHORT(info->data+info->hhea + 6);
11565 if (lineGap) *lineGap = nk_ttSHORT(info->data+info->hhea + 8);
11568 nk_tt_ScaleForPixelHeight(
const struct nk_tt_fontinfo *info,
float height)
11570 int fheight = nk_ttSHORT(info->data + info->hhea + 4) - nk_ttSHORT(info->data + info->hhea + 6);
11571 return (
float) height / (float)fheight;
11574 nk_tt_ScaleForMappingEmToPixels(
const struct nk_tt_fontinfo *info,
float pixels)
11576 int unitsPerEm = nk_ttUSHORT(info->data + info->head + 18);
11577 return pixels / (float)unitsPerEm;
11584 nk_tt_GetGlyphBitmapBoxSubpixel(
const struct nk_tt_fontinfo *font,
11585 int glyph,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
11586 int *ix0,
int *iy0,
int *ix1,
int *iy1)
11589 if (!nk_tt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
11597 if (ix0) *ix0 = nk_ifloorf((
float)x0 * scale_x + shift_x);
11598 if (iy0) *iy0 = nk_ifloorf((
float)-y1 * scale_y + shift_y);
11599 if (ix1) *ix1 = nk_iceilf ((
float)x1 * scale_x + shift_x);
11600 if (iy1) *iy1 = nk_iceilf ((
float)-y0 * scale_y + shift_y);
11604 nk_tt_GetGlyphBitmapBox(
const struct nk_tt_fontinfo *font,
int glyph,
11605 float scale_x,
float scale_y,
int *ix0,
int *iy0,
int *ix1,
int *iy1)
11607 nk_tt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1);
11614 nk_tt__hheap_alloc(
struct nk_tt__hheap *hh,
nk_size size)
11616 if (hh->first_free) {
11617 void *p = hh->first_free;
11618 hh->first_free = * (
void **) p;
11621 if (hh->num_remaining_in_head_chunk == 0) {
11622 int count = (size < 32 ? 2000 : size < 128 ? 800 : 100);
11623 struct nk_tt__hheap_chunk *c = (
struct nk_tt__hheap_chunk *)
11624 hh->alloc.alloc(hh->alloc.userdata, 0,
11625 sizeof(
struct nk_tt__hheap_chunk) + size * (
nk_size)count);
11626 if (c == 0)
return 0;
11627 c->next = hh->head;
11629 hh->num_remaining_in_head_chunk = count;
11631 --hh->num_remaining_in_head_chunk;
11632 return (
char *) (hh->head) + size * (
nk_size)hh->num_remaining_in_head_chunk;
11636 nk_tt__hheap_free(
struct nk_tt__hheap *hh,
void *p)
11638 *(
void **) p = hh->first_free;
11639 hh->first_free = p;
11642 nk_tt__hheap_cleanup(
struct nk_tt__hheap *hh)
11644 struct nk_tt__hheap_chunk *c = hh->head;
11646 struct nk_tt__hheap_chunk *n = c->next;
11647 hh->alloc.free(hh->alloc.userdata, c);
11652 nk_tt__new_active(
struct nk_tt__hheap *hh,
struct nk_tt__edge *e,
11653 int off_x,
float start_point)
11655 struct nk_tt__active_edge *z = (
struct nk_tt__active_edge *)
11656 nk_tt__hheap_alloc(hh,
sizeof(*z));
11657 float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
11661 z->fdy = (dxdy != 0) ? (1/dxdy): 0;
11662 z->fx = e->x0 + dxdy * (start_point - e->y0);
11663 z->fx -= (float)off_x;
11664 z->direction = e->invert ? 1.0f : -1.0f;
11671 nk_tt__handle_clipped_edge(
float *scanline,
int x,
struct nk_tt__active_edge *e,
11672 float x0,
float y0,
float x1,
float y1)
11674 if (y0 == y1)
return;
11675 NK_ASSERT(y0 < y1);
11676 NK_ASSERT(e->sy <= e->ey);
11677 if (y0 > e->ey)
return;
11678 if (y1 < e->sy)
return;
11680 x0 += (x1-x0) * (e->sy - y0) / (y1-y0);
11684 x1 += (x1-x0) * (e->ey - y1) / (y1-y0);
11688 if (x0 == x) NK_ASSERT(x1 <= x+1);
11689 else if (x0 == x+1) NK_ASSERT(x1 >= x);
11690 else if (x0 <= x) NK_ASSERT(x1 <= x);
11691 else if (x0 >= x+1) NK_ASSERT(x1 >= x+1);
11692 else NK_ASSERT(x1 >= x && x1 <= x+1);
11694 if (x0 <= x && x1 <= x)
11695 scanline[x] += e->direction * (y1-y0);
11696 else if (x0 >= x+1 && x1 >= x+1);
11698 NK_ASSERT(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1);
11700 scanline[x] += (float)e->direction * (
float)(y1-y0) * (1.0f-((x0-(
float)x)+(x1-(float)x))/2.0f);
11704 nk_tt__fill_active_edges_new(
float *scanline,
float *scanline_fill,
int len,
11705 struct nk_tt__active_edge *e,
float y_top)
11707 float y_bottom = y_top+1;
11712 NK_ASSERT(e->ey >= y_top);
11717 nk_tt__handle_clipped_edge(scanline,(
int) x0,e, x0,y_top, x0,y_bottom);
11718 nk_tt__handle_clipped_edge(scanline_fill-1,(
int) x0+1,e, x0,y_top, x0,y_bottom);
11720 nk_tt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom);
11726 float xb = x0 + dx;
11727 float x_top, x_bottom;
11730 NK_ASSERT(e->sy <= y_bottom && e->ey >= y_top);
11735 if (e->sy > y_top) {
11736 x_top = x0 + dx * (e->sy - y_top);
11743 if (e->ey < y_bottom) {
11744 x_bottom = x0 + dx * (e->ey - y_top);
11751 if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len)
11754 if ((
int) x_top == (int) x_bottom) {
11757 int x = (int) x_top;
11759 NK_ASSERT(x >= 0 && x < len);
11760 scanline[x] += e->direction * (1.0f-(((float)x_top - (
float)x) + ((
float)x_bottom-(float)x))/2.0f) * (float)height;
11761 scanline_fill[x] += e->direction * (float)height;
11764 float y_crossing, step, sign, area;
11766 if (x_top > x_bottom)
11770 y0 = y_bottom - (y0 - y_top);
11771 y1 = y_bottom - (y1 - y_top);
11772 t = y0; y0 = y1; y1 = t;
11773 t = x_bottom; x_bottom = x_top; x_top = t;
11776 t = x0; x0 = xb; xb = t;
11780 x2 = (int) x_bottom;
11782 y_crossing = ((float)x1+1 - (
float)x0) * (
float)dy + (float)y_top;
11784 sign = e->direction;
11786 area = sign * (y_crossing-y0);
11788 scanline[x1] += area * (1.0f-((float)((
float)x_top - (float)x1)+(float)(x1+1-x1))/2.0f);
11791 for (x = x1+1; x < x2; ++x) {
11792 scanline[x] += area + step/2;
11795 y_crossing += (float)dy * (
float)(x2 - (x1+1));
11797 scanline[x2] += area + sign * (1.0f-((float)(x2-x2)+((float)x_bottom-(
float)x2))/2.0f) * (y1-y_crossing);
11798 scanline_fill[x2] += sign * (y1-y0);
11808 for (x=0; x < len; ++x)
11825 float x1 = (float) (x);
11826 float x2 = (float) (x+1);
11828 float y3 = y_bottom;
11831 yb = ((float)x - x0) / dx + y_top;
11832 y2 = ((float)x+1 - x0) / dx + y_top;
11834 if (x0 < x1 && x3 > x2) {
11835 nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb);
11836 nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x2,y2);
11837 nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
11838 }
else if (x3 < x1 && x0 > x2) {
11839 nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2);
11840 nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x1,yb);
11841 nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3);
11842 }
else if (x0 < x1 && x3 > x1) {
11843 nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb);
11844 nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3);
11845 }
else if (x3 < x1 && x0 > x1) {
11846 nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb);
11847 nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3);
11848 }
else if (x0 < x2 && x3 > x2) {
11849 nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2);
11850 nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
11851 }
else if (x3 < x2 && x0 > x2) {
11852 nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2);
11853 nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
11855 nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x3,y3);
11864 nk_tt__rasterize_sorted_edges(
struct nk_tt__bitmap *result,
struct nk_tt__edge *e,
11865 int n,
int vsubsample,
int off_x,
int off_y,
struct nk_allocator *alloc)
11868 struct nk_tt__hheap hh;
11869 struct nk_tt__active_edge *active = 0;
11871 float scanline_data[129], *scanline, *scanline2;
11877 if (result->w > 64)
11878 scanline = (
float *) alloc->
alloc(alloc->
userdata,0, (
nk_size)(result->w*2+1) *
sizeof(
float));
11879 else scanline = scanline_data;
11881 scanline2 = scanline + result->w;
11883 e[n].y0 = (float) (off_y + result->h) + 1;
11885 while (j < result->h)
11888 float scan_y_top = (float)y + 0.0f;
11889 float scan_y_bottom = (float)y + 1.0f;
11890 struct nk_tt__active_edge **step = &active;
11892 NK_MEMSET(scanline , 0, (
nk_size)result->w*
sizeof(scanline[0]));
11893 NK_MEMSET(scanline2, 0, (
nk_size)(result->w+1)*
sizeof(scanline[0]));
11898 struct nk_tt__active_edge * z = *step;
11899 if (z->ey <= scan_y_top) {
11901 NK_ASSERT(z->direction);
11903 nk_tt__hheap_free(&hh, z);
11905 step = &((*step)->next);
11910 while (e->y0 <= scan_y_bottom) {
11911 if (e->y0 != e->y1) {
11912 struct nk_tt__active_edge *z = nk_tt__new_active(&hh, e, off_x, scan_y_top);
11914 NK_ASSERT(z->ey >= scan_y_top);
11925 nk_tt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top);
11929 for (i=0; i < result->w; ++i) {
11932 sum += scanline2[i];
11933 k = scanline[i] + sum;
11934 k = (float)
NK_ABS(k) * 255.0f + 0.5f;
11936 if (m > 255) m = 255;
11937 result->pixels[j*result->stride + i] = (
unsigned char) m;
11943 struct nk_tt__active_edge *z = *step;
11945 step = &((*step)->next);
11950 nk_tt__hheap_cleanup(&hh);
11951 if (scanline != scanline_data)
11955 nk_tt__sort_edges_ins_sort(
struct nk_tt__edge *p,
int n)
11958 #define NK_TT__COMPARE(a,b) ((a)->y0 < (b)->y0)
11959 for (i=1; i < n; ++i) {
11960 struct nk_tt__edge t = p[i], *a = &t;
11963 struct nk_tt__edge *b = &p[j-1];
11964 int c = NK_TT__COMPARE(a,b);
11974 nk_tt__sort_edges_quicksort(
struct nk_tt__edge *p,
int n)
11978 struct nk_tt__edge t;
11979 int c01,c12,c,m,i,j;
11983 c01 = NK_TT__COMPARE(&p[0],&p[m]);
11984 c12 = NK_TT__COMPARE(&p[m],&p[n-1]);
11990 c = NK_TT__COMPARE(&p[0],&p[n-1]);
11993 z = (c == c12) ? 0 : n-1;
12012 if (!NK_TT__COMPARE(&p[i], &p[0]))
break;
12015 if (!NK_TT__COMPARE(&p[0], &p[j]))
break;
12031 nk_tt__sort_edges_quicksort(p,j);
12035 nk_tt__sort_edges_quicksort(p+i, n-i);
12041 nk_tt__sort_edges(
struct nk_tt__edge *p,
int n)
12043 nk_tt__sort_edges_quicksort(p, n);
12044 nk_tt__sort_edges_ins_sort(p, n);
12047 nk_tt__rasterize(
struct nk_tt__bitmap *result,
struct nk_tt__point *pts,
12048 int *wcount,
int windings,
float scale_x,
float scale_y,
12049 float shift_x,
float shift_y,
int off_x,
int off_y,
int invert,
12052 float y_scale_inv = invert ? -scale_y : scale_y;
12053 struct nk_tt__edge *e;
12055 int vsubsample = 1;
12060 for (i=0; i < windings; ++i)
12063 e = (
struct nk_tt__edge*)
12065 if (e == 0)
return;
12069 for (i=0; i < windings; ++i)
12071 struct nk_tt__point *p = pts + m;
12074 for (k=0; k < wcount[i]; j=k++) {
12077 if (p[j].y == p[k].y)
12082 if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
12086 e[n].x0 = p[a].x * scale_x + shift_x;
12087 e[n].y0 = (p[a].y * y_scale_inv + shift_y) * (
float)vsubsample;
12088 e[n].x1 = p[b].x * scale_x + shift_x;
12089 e[n].y1 = (p[b].y * y_scale_inv + shift_y) * (
float)vsubsample;
12096 nk_tt__sort_edges(e, n);
12098 nk_tt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, alloc);
12102 nk_tt__add_point(
struct nk_tt__point *points,
int n,
float x,
float y)
12104 if (!points)
return;
12109 nk_tt__tesselate_curve(
struct nk_tt__point *points,
int *num_points,
12110 float x0,
float y0,
float x1,
float y1,
float x2,
float y2,
12111 float objspace_flatness_squared,
int n)
12116 float mx = (x0 + 2*x1 + x2)/4;
12117 float my = (y0 + 2*y1 + y2)/4;
12119 float dx = (x0+x2)/2 - mx;
12120 float dy = (y0+y2)/2 - my;
12125 if (dx*dx+dy*dy > objspace_flatness_squared) {
12126 nk_tt__tesselate_curve(points, num_points, x0,y0,
12127 (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1);
12128 nk_tt__tesselate_curve(points, num_points, mx,my,
12129 (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1);
12131 nk_tt__add_point(points, *num_points,x2,y2);
12132 *num_points = *num_points+1;
12137 nk_tt_FlattenCurves(
struct nk_tt_vertex *vertices,
int num_verts,
12138 float objspace_flatness,
int **contour_lengths,
int *num_contours,
12142 struct nk_tt__point *points=0;
12144 float objspace_flatness_squared = objspace_flatness * objspace_flatness;
12151 for (i=0; i < num_verts; ++i)
12152 if (vertices[i].type == NK_TT_vmove) ++n;
12155 if (n == 0)
return 0;
12157 *contour_lengths = (
int *)
12159 if (*contour_lengths == 0) {
12165 for (pass=0; pass < 2; ++pass)
12169 points = (
struct nk_tt__point *)
12171 if (points == 0)
goto error;
12176 for (i=0; i < num_verts; ++i)
12178 switch (vertices[i].type) {
12182 (*contour_lengths)[n] = num_points - start;
12184 start = num_points;
12186 x = vertices[i].x, y = vertices[i].y;
12187 nk_tt__add_point(points, num_points++, x,y);
12190 x = vertices[i].x, y = vertices[i].y;
12191 nk_tt__add_point(points, num_points++, x, y);
12194 nk_tt__tesselate_curve(points, &num_points, x,y,
12195 vertices[i].cx, vertices[i].cy,
12196 vertices[i].x, vertices[i].y,
12197 objspace_flatness_squared, 0);
12198 x = vertices[i].x, y = vertices[i].y;
12203 (*contour_lengths)[n] = num_points - start;
12210 *contour_lengths = 0;
12215 nk_tt_Rasterize(
struct nk_tt__bitmap *result,
float flatness_in_pixels,
12216 struct nk_tt_vertex *vertices,
int num_verts,
12217 float scale_x,
float scale_y,
float shift_x,
float shift_y,
12218 int x_off,
int y_off,
int invert,
struct nk_allocator *alloc)
12220 float scale = scale_x > scale_y ? scale_y : scale_x;
12221 int winding_count, *winding_lengths;
12222 struct nk_tt__point *windings = nk_tt_FlattenCurves(vertices, num_verts,
12223 flatness_in_pixels / scale, &winding_lengths, &winding_count, alloc);
12227 nk_tt__rasterize(result, windings, winding_lengths, winding_count,
12228 scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, alloc);
12234 nk_tt_MakeGlyphBitmapSubpixel(
const struct nk_tt_fontinfo *info,
unsigned char *output,
12235 int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
12236 float shift_x,
float shift_y,
int glyph,
struct nk_allocator *alloc)
12239 struct nk_tt_vertex *vertices;
12240 int num_verts = nk_tt_GetGlyphShape(info, alloc, glyph, &vertices);
12241 struct nk_tt__bitmap gbm;
12243 nk_tt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x,
12244 shift_y, &ix0,&iy0,0,0);
12245 gbm.pixels = output;
12248 gbm.stride = out_stride;
12250 if (gbm.w && gbm.h)
12251 nk_tt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y,
12252 shift_x, shift_y, ix0,iy0, 1, alloc);
12260 nk_tt_PackBegin(
struct nk_tt_pack_context *spc,
unsigned char *pixels,
12261 int pw,
int ph,
int stride_in_bytes,
int padding,
struct nk_allocator *alloc)
12263 int num_nodes = pw - padding;
12264 struct nk_rp_context *context = (
struct nk_rp_context *)
12266 struct nk_rp_node *nodes = (
struct nk_rp_node*)
12269 if (context == 0 || nodes == 0) {
12270 if (context != 0) alloc->
free(alloc->
userdata, context);
12277 spc->pixels = pixels;
12278 spc->pack_info = context;
12279 spc->nodes = nodes;
12280 spc->padding = padding;
12281 spc->stride_in_bytes = (stride_in_bytes != 0) ? stride_in_bytes : pw;
12282 spc->h_oversample = 1;
12283 spc->v_oversample = 1;
12285 nk_rp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
12287 NK_MEMSET(pixels, 0, (
nk_size)(pw*ph));
12291 nk_tt_PackEnd(
struct nk_tt_pack_context *spc,
struct nk_allocator *alloc)
12297 nk_tt_PackSetOversampling(
struct nk_tt_pack_context *spc,
12298 unsigned int h_oversample,
unsigned int v_oversample)
12300 NK_ASSERT(h_oversample <= NK_TT_MAX_OVERSAMPLE);
12301 NK_ASSERT(v_oversample <= NK_TT_MAX_OVERSAMPLE);
12302 if (h_oversample <= NK_TT_MAX_OVERSAMPLE)
12303 spc->h_oversample = h_oversample;
12304 if (v_oversample <= NK_TT_MAX_OVERSAMPLE)
12305 spc->v_oversample = v_oversample;
12308 nk_tt__h_prefilter(
unsigned char *pixels,
int w,
int h,
int stride_in_bytes,
12311 unsigned char buffer[NK_TT_MAX_OVERSAMPLE];
12312 int safe_w = w - kernel_width;
12315 for (j=0; j < h; ++j)
12318 unsigned int total;
12319 NK_MEMSET(buffer, 0, (
nk_size)kernel_width);
12324 switch (kernel_width) {
12326 for (i=0; i <= safe_w; ++i) {
12327 total += (
unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12328 buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12329 pixels[i] = (
unsigned char) (total / 2);
12333 for (i=0; i <= safe_w; ++i) {
12334 total += (
unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12335 buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12336 pixels[i] = (
unsigned char) (total / 3);
12340 for (i=0; i <= safe_w; ++i) {
12341 total += (
unsigned int)pixels[i] - buffer[i & NK_TT__OVER_MASK];
12342 buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12343 pixels[i] = (
unsigned char) (total / 4);
12347 for (i=0; i <= safe_w; ++i) {
12348 total += (
unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12349 buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12350 pixels[i] = (
unsigned char) (total / 5);
12354 for (i=0; i <= safe_w; ++i) {
12355 total += (
unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12356 buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12357 pixels[i] = (
unsigned char) (total / (
unsigned int)kernel_width);
12362 for (; i < w; ++i) {
12363 NK_ASSERT(pixels[i] == 0);
12364 total -= (
unsigned int)(buffer[i & NK_TT__OVER_MASK]);
12365 pixels[i] = (
unsigned char) (total / (
unsigned int)kernel_width);
12367 pixels += stride_in_bytes;
12371 nk_tt__v_prefilter(
unsigned char *pixels,
int w,
int h,
int stride_in_bytes,
12374 unsigned char buffer[NK_TT_MAX_OVERSAMPLE];
12375 int safe_h = h - kernel_width;
12378 for (j=0; j < w; ++j)
12381 unsigned int total;
12382 NK_MEMSET(buffer, 0, (
nk_size)kernel_width);
12387 switch (kernel_width) {
12389 for (i=0; i <= safe_h; ++i) {
12390 total += (
unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12391 buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12392 pixels[i*stride_in_bytes] = (
unsigned char) (total / 2);
12396 for (i=0; i <= safe_h; ++i) {
12397 total += (
unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12398 buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12399 pixels[i*stride_in_bytes] = (
unsigned char) (total / 3);
12403 for (i=0; i <= safe_h; ++i) {
12404 total += (
unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12405 buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12406 pixels[i*stride_in_bytes] = (
unsigned char) (total / 4);
12410 for (i=0; i <= safe_h; ++i) {
12411 total += (
unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12412 buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12413 pixels[i*stride_in_bytes] = (
unsigned char) (total / 5);
12417 for (i=0; i <= safe_h; ++i) {
12418 total += (
unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12419 buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12420 pixels[i*stride_in_bytes] = (
unsigned char) (total / (
unsigned int)kernel_width);
12425 for (; i < h; ++i) {
12426 NK_ASSERT(pixels[i*stride_in_bytes] == 0);
12427 total -= (
unsigned int)(buffer[i & NK_TT__OVER_MASK]);
12428 pixels[i*stride_in_bytes] = (
unsigned char) (total / (
unsigned int)kernel_width);
12434 nk_tt__oversample_shift(
int oversample)
12443 return (
float)-(oversample - 1) / (2.0f * (
float)oversample);
12446 nk_tt_PackFontRangesGatherRects(
struct nk_tt_pack_context *spc,
12447 struct nk_tt_fontinfo *info,
struct nk_tt_pack_range *ranges,
12448 int num_ranges,
struct nk_rp_rect *rects)
12454 for (i=0; i < num_ranges; ++i) {
12455 float fh = ranges[i].font_size;
12456 float scale = (fh > 0) ? nk_tt_ScaleForPixelHeight(info, fh):
12457 nk_tt_ScaleForMappingEmToPixels(info, -fh);
12458 ranges[i].h_oversample = (
unsigned char) spc->h_oversample;
12459 ranges[i].v_oversample = (
unsigned char) spc->v_oversample;
12460 for (j=0; j < ranges[i].num_chars; ++j) {
12462 int codepoint = ranges[i].first_unicode_codepoint_in_range ?
12463 ranges[i].first_unicode_codepoint_in_range + j :
12464 ranges[i].array_of_unicode_codepoints[j];
12466 int glyph = nk_tt_FindGlyphIndex(info, codepoint);
12467 nk_tt_GetGlyphBitmapBoxSubpixel(info,glyph, scale * (
float)spc->h_oversample,
12468 scale * (
float)spc->v_oversample, 0,0, &x0,&y0,&x1,&y1);
12469 rects[k].w = (nk_rp_coord) (x1-x0 + spc->padding + (
int)spc->h_oversample-1);
12470 rects[k].h = (nk_rp_coord) (y1-y0 + spc->padding + (
int)spc->v_oversample-1);
12477 nk_tt_PackFontRangesRenderIntoRects(
struct nk_tt_pack_context *spc,
12478 struct nk_tt_fontinfo *info,
struct nk_tt_pack_range *ranges,
12479 int num_ranges,
struct nk_rp_rect *rects,
struct nk_allocator *alloc)
12481 int i,j,k, return_value = 1;
12483 int old_h_over = (int)spc->h_oversample;
12484 int old_v_over = (
int)spc->v_oversample;
12488 for (i=0; i < num_ranges; ++i)
12490 float fh = ranges[i].font_size;
12491 float recip_h,recip_v,sub_x,sub_y;
12492 float scale = fh > 0 ? nk_tt_ScaleForPixelHeight(info, fh):
12493 nk_tt_ScaleForMappingEmToPixels(info, -fh);
12495 spc->h_oversample = ranges[i].h_oversample;
12496 spc->v_oversample = ranges[i].v_oversample;
12498 recip_h = 1.0f / (float)spc->h_oversample;
12499 recip_v = 1.0f / (
float)spc->v_oversample;
12501 sub_x = nk_tt__oversample_shift((
int)spc->h_oversample);
12502 sub_y = nk_tt__oversample_shift((
int)spc->v_oversample);
12504 for (j=0; j < ranges[i].num_chars; ++j)
12506 struct nk_rp_rect *r = &rects[k];
12509 struct nk_tt_packedchar *bc = &ranges[i].chardata_for_range[j];
12510 int advance, lsb, x0,y0,x1,y1;
12511 int codepoint = ranges[i].first_unicode_codepoint_in_range ?
12512 ranges[i].first_unicode_codepoint_in_range + j :
12513 ranges[i].array_of_unicode_codepoints[j];
12514 int glyph = nk_tt_FindGlyphIndex(info, codepoint);
12515 nk_rp_coord pad = (nk_rp_coord) spc->padding;
12518 r->x = (nk_rp_coord)((int)r->x + (
int)pad);
12519 r->y = (nk_rp_coord)((
int)r->y + (int)pad);
12520 r->w = (nk_rp_coord)((
int)r->w - (int)pad);
12521 r->h = (nk_rp_coord)((
int)r->h - (int)pad);
12523 nk_tt_GetGlyphHMetrics(info, glyph, &advance, &lsb);
12524 nk_tt_GetGlyphBitmapBox(info, glyph, scale * (
float)spc->h_oversample,
12525 (scale * (
float)spc->v_oversample), &x0,&y0,&x1,&y1);
12526 nk_tt_MakeGlyphBitmapSubpixel(info, spc->pixels + r->x + r->y*spc->stride_in_bytes,
12527 (
int)(r->w - spc->h_oversample+1), (
int)(r->h - spc->v_oversample+1),
12528 spc->stride_in_bytes, scale * (
float)spc->h_oversample,
12529 scale * (
float)spc->v_oversample, 0,0, glyph, alloc);
12531 if (spc->h_oversample > 1)
12532 nk_tt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
12533 r->w, r->h, spc->stride_in_bytes, (
int)spc->h_oversample);
12535 if (spc->v_oversample > 1)
12536 nk_tt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
12537 r->w, r->h, spc->stride_in_bytes, (
int)spc->v_oversample);
12543 bc->xadvance = scale * (float)advance;
12544 bc->xoff = (float) x0 * recip_h + sub_x;
12545 bc->yoff = (float) y0 * recip_v + sub_y;
12546 bc->xoff2 = ((float)x0 + r->w) * recip_h + sub_x;
12547 bc->yoff2 = ((float)y0 + r->h) * recip_v + sub_y;
12555 spc->h_oversample = (
unsigned int)old_h_over;
12556 spc->v_oversample = (
unsigned int)old_v_over;
12557 return return_value;
12560 nk_tt_GetPackedQuad(
struct nk_tt_packedchar *chardata,
int pw,
int ph,
12561 int char_index,
float *xpos,
float *ypos,
struct nk_tt_aligned_quad *q,
12562 int align_to_integer)
12564 float ipw = 1.0f / (float)pw, iph = 1.0f / (
float)ph;
12565 struct nk_tt_packedchar *b = (
struct nk_tt_packedchar*)(chardata + char_index);
12566 if (align_to_integer) {
12567 int tx = nk_ifloorf((*xpos + b->xoff) + 0.5f);
12568 int ty = nk_ifloorf((*ypos + b->yoff) + 0.5f);
12570 float x = (float)tx;
12571 float y = (float)ty;
12575 q->x1 = x + b->xoff2 - b->xoff;
12576 q->y1 = y + b->yoff2 - b->yoff;
12578 q->x0 = *xpos + b->xoff;
12579 q->y0 = *ypos + b->yoff;
12580 q->x1 = *xpos + b->xoff2;
12581 q->y1 = *ypos + b->yoff2;
12583 q->s0 = b->x0 * ipw;
12584 q->t0 = b->y0 * iph;
12585 q->s1 = b->x1 * ipw;
12586 q->t1 = b->y1 * iph;
12587 *xpos += b->xadvance;
12595 struct nk_font_bake_data {
12596 struct nk_tt_fontinfo info;
12597 struct nk_rp_rect *rects;
12598 struct nk_tt_pack_range *ranges;
12602 struct nk_font_baker {
12604 struct nk_tt_pack_context spc;
12605 struct nk_font_bake_data *build;
12606 struct nk_tt_packedchar *packed_chars;
12607 struct nk_rp_rect *rects;
12608 struct nk_tt_pack_range *ranges;
12618 nk_range_count(
const nk_rune *range)
12622 if (!range)
return 0;
12623 while (*(iter++) != 0);
12624 return (iter == range) ? 0 : (int)((iter - range)/2);
12627 nk_range_glyph_count(
const nk_rune *range,
int count)
12630 int total_glyphs = 0;
12631 for (i = 0; i < count; ++i) {
12636 diff = (int)((t - f) + 1);
12637 total_glyphs += diff;
12639 return total_glyphs;
12642 nk_font_default_glyph_ranges(
void)
12648 nk_font_chinese_glyph_ranges(
void)
12661 nk_font_cyrillic_glyph_ranges(
void)
12673 nk_font_korean_glyph_ranges(
void)
12684 nk_font_baker_memory(
nk_size *temp,
int *glyph_count,
12685 struct nk_font_config *config_list,
int count)
12687 int range_count = 0;
12688 int total_range_count = 0;
12689 struct nk_font_config *iter, *i;
12691 NK_ASSERT(config_list);
12692 NK_ASSERT(glyph_count);
12693 if (!config_list) {
12699 for (iter = config_list; iter; iter = iter->next) {
12701 do {
if (!i->range) iter->range = nk_font_default_glyph_ranges();
12702 range_count = nk_range_count(i->range);
12703 total_range_count += range_count;
12704 *glyph_count += nk_range_glyph_count(i->range, range_count);
12705 }
while ((i = i->n) != iter);
12707 *temp = (
nk_size)*glyph_count *
sizeof(
struct nk_rp_rect);
12708 *temp += (
nk_size)total_range_count *
sizeof(
struct nk_tt_pack_range);
12709 *temp += (
nk_size)*glyph_count *
sizeof(
struct nk_tt_packedchar);
12710 *temp += (
nk_size)count *
sizeof(
struct nk_font_bake_data);
12711 *temp +=
sizeof(
struct nk_font_baker);
12712 *temp += nk_rect_align + nk_range_align + nk_char_align;
12713 *temp += nk_build_align + nk_baker_align;
12716 nk_font_baker(
void *memory,
int glyph_count,
int count,
struct nk_allocator *alloc)
12718 struct nk_font_baker *baker;
12719 if (!memory)
return 0;
12721 baker = (
struct nk_font_baker*)
NK_ALIGN_PTR(memory, nk_baker_align);
12722 baker->build = (
struct nk_font_bake_data*)
NK_ALIGN_PTR((baker + 1), nk_build_align);
12723 baker->packed_chars = (
struct nk_tt_packedchar*)
NK_ALIGN_PTR((baker->build + count), nk_char_align);
12724 baker->rects = (
struct nk_rp_rect*)
NK_ALIGN_PTR((baker->packed_chars + glyph_count), nk_rect_align);
12725 baker->ranges = (
struct nk_tt_pack_range*)
NK_ALIGN_PTR((baker->rects + glyph_count), nk_range_align);
12726 baker->alloc = *alloc;
12730 nk_font_bake_pack(
struct nk_font_baker *baker,
12731 nk_size *image_memory,
int *width,
int *height,
struct nk_recti *custom,
12732 const struct nk_font_config *config_list,
int count,
12736 const struct nk_font_config *config_iter, *it;
12737 int total_glyph_count = 0;
12738 int total_range_count = 0;
12739 int range_count = 0;
12742 NK_ASSERT(image_memory);
12745 NK_ASSERT(config_list);
12749 if (!image_memory || !width || !height || !config_list || !count)
return nk_false;
12750 for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
12752 do {range_count = nk_range_count(it->range);
12753 total_range_count += range_count;
12754 total_glyph_count += nk_range_glyph_count(it->range, range_count);
12755 }
while ((it = it->n) != config_iter);
12758 for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
12760 do {
if (!nk_tt_InitFont(&baker->build[i++].info, (
const unsigned char*)it->ttf_blob, 0))
12762 }
while ((it = it->n) != config_iter);
12765 *width = (total_glyph_count > 1000) ? 1024 : 512;
12766 nk_tt_PackBegin(&baker->spc, 0, (
int)*width, (
int)max_height, 0, 1, alloc);
12775 struct nk_rp_rect custom_space;
12776 nk_zero(&custom_space,
sizeof(custom_space));
12777 custom_space.w = (nk_rp_coord)(custom->
w);
12778 custom_space.h = (nk_rp_coord)(custom->
h);
12780 nk_tt_PackSetOversampling(&baker->spc, 1, 1);
12781 nk_rp_pack_rects((
struct nk_rp_context*)baker->spc.pack_info, &custom_space, 1);
12782 *height =
NK_MAX(*height, (
int)(custom_space.y + custom_space.h));
12784 custom->
x = (short)custom_space.x;
12785 custom->
y = (
short)custom_space.y;
12786 custom->
w = (short)custom_space.w;
12787 custom->
h = (
short)custom_space.h;
12791 for (input_i = 0, config_iter = config_list; input_i < count && config_iter;
12792 config_iter = config_iter->next) {
12797 const struct nk_font_config *cfg = it;
12798 struct nk_font_bake_data *tmp = &baker->build[input_i++];
12801 glyph_count = 0; range_count = 0;
12802 for (in_range = cfg->range; in_range[0] && in_range[1]; in_range += 2) {
12803 glyph_count += (int)(in_range[1] - in_range[0]) + 1;
12808 tmp->ranges = baker->ranges + range_n;
12809 tmp->range_count = (
nk_rune)range_count;
12810 range_n += range_count;
12811 for (i = 0; i < range_count; ++i) {
12812 in_range = &cfg->range[i * 2];
12813 tmp->ranges[i].font_size = cfg->size;
12814 tmp->ranges[i].first_unicode_codepoint_in_range = (int)in_range[0];
12815 tmp->ranges[i].num_chars = (int)(in_range[1]- in_range[0]) + 1;
12816 tmp->ranges[i].chardata_for_range = baker->packed_chars + char_n;
12817 char_n += tmp->ranges[i].num_chars;
12821 tmp->rects = baker->rects + rect_n;
12822 rect_n += glyph_count;
12823 nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
12824 n = nk_tt_PackFontRangesGatherRects(&baker->spc, &tmp->info,
12825 tmp->ranges, (
int)tmp->range_count, tmp->rects);
12826 nk_rp_pack_rects((
struct nk_rp_context*)baker->spc.pack_info, tmp->rects, (
int)n);
12829 for (i = 0; i < n; ++i) {
12830 if (tmp->rects[i].was_packed)
12831 *height =
NK_MAX(*height, tmp->rects[i].y + tmp->rects[i].h);
12833 }
while ((it = it->n) != config_iter);
12835 NK_ASSERT(rect_n == total_glyph_count);
12836 NK_ASSERT(char_n == total_glyph_count);
12837 NK_ASSERT(range_n == total_range_count);
12839 *height = (int)nk_round_up_pow2((
nk_uint)*height);
12844 nk_font_bake(
struct nk_font_baker *baker,
void *image_memory,
int width,
int height,
12845 struct nk_font_glyph *glyphs,
int glyphs_count,
12846 const struct nk_font_config *config_list,
int font_count)
12850 const struct nk_font_config *config_iter;
12851 const struct nk_font_config *it;
12853 NK_ASSERT(image_memory);
12856 NK_ASSERT(config_list);
12858 NK_ASSERT(font_count);
12859 NK_ASSERT(glyphs_count);
12860 if (!image_memory || !width || !height || !config_list ||
12861 !font_count || !glyphs || !glyphs_count)
12866 baker->spc.pixels = (
unsigned char*)image_memory;
12867 baker->spc.height = (int)height;
12868 for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
12869 config_iter = config_iter->next) {
12871 do {
const struct nk_font_config *cfg = it;
12872 struct nk_font_bake_data *tmp = &baker->build[input_i++];
12873 nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
12874 nk_tt_PackFontRangesRenderIntoRects(&baker->spc, &tmp->info, tmp->ranges,
12875 (
int)tmp->range_count, tmp->rects, &baker->alloc);
12876 }
while ((it = it->n) != config_iter);
12877 } nk_tt_PackEnd(&baker->spc, &baker->alloc);
12880 for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
12881 config_iter = config_iter->next) {
12886 const struct nk_font_config *cfg = it;
12887 struct nk_font_bake_data *tmp = &baker->build[input_i++];
12888 struct nk_baked_font *dst_font = cfg->font;
12890 float font_scale = nk_tt_ScaleForPixelHeight(&tmp->info, cfg->size);
12891 int unscaled_ascent, unscaled_descent, unscaled_line_gap;
12892 nk_tt_GetFontVMetrics(&tmp->info, &unscaled_ascent, &unscaled_descent,
12893 &unscaled_line_gap);
12896 if (!cfg->merge_mode) {
12897 dst_font->ranges = cfg->range;
12898 dst_font->height = cfg->size;
12899 dst_font->ascent = ((float)unscaled_ascent * font_scale);
12900 dst_font->descent = ((float)unscaled_descent * font_scale);
12901 dst_font->glyph_offset = glyph_n;
12904 dst_font->glyph_count = 0;
12908 for (i = 0; i < tmp->range_count; ++i) {
12909 struct nk_tt_pack_range *range = &tmp->ranges[i];
12910 for (char_idx = 0; char_idx < range->num_chars; char_idx++)
12913 float dummy_x = 0, dummy_y = 0;
12914 struct nk_tt_aligned_quad q;
12915 struct nk_font_glyph *glyph;
12918 const struct nk_tt_packedchar *pc = &range->chardata_for_range[char_idx];
12919 if (!pc->x0 && !pc->x1 && !pc->y0 && !pc->y1)
continue;
12920 codepoint = (
nk_rune)(range->first_unicode_codepoint_in_range + char_idx);
12921 nk_tt_GetPackedQuad(range->chardata_for_range, (
int)width,
12922 (
int)height, char_idx, &dummy_x, &dummy_y, &q, 0);
12925 glyph = &glyphs[dst_font->glyph_offset + dst_font->glyph_count + (
unsigned int)glyph_count];
12926 glyph->codepoint = codepoint;
12927 glyph->x0 = q.x0; glyph->y0 = q.y0;
12928 glyph->x1 = q.x1; glyph->y1 = q.y1;
12929 glyph->y0 += (dst_font->ascent + 0.5f);
12930 glyph->y1 += (dst_font->ascent + 0.5f);
12931 glyph->w = glyph->x1 - glyph->x0 + 0.5f;
12932 glyph->h = glyph->y1 - glyph->y0;
12934 if (cfg->coord_type == NK_COORD_PIXEL) {
12935 glyph->u0 = q.s0 * (float)width;
12936 glyph->v0 = q.t0 * (float)height;
12937 glyph->u1 = q.s1 * (float)width;
12938 glyph->v1 = q.t1 * (float)height;
12945 glyph->xadvance = (pc->xadvance + cfg->spacing.x);
12946 if (cfg->pixel_snap)
12947 glyph->xadvance = (float)(
int)(glyph->xadvance + 0.5f);
12951 dst_font->glyph_count += glyph_count;
12952 glyph_n += glyph_count;
12953 }
while ((it = it->n) != config_iter);
12957 nk_font_bake_custom_data(
void *img_memory,
int img_width,
int img_height,
12958 struct nk_recti img_dst,
const char *texture_data_mask,
int tex_width,
12959 int tex_height,
char white,
char black)
12966 NK_ASSERT(img_memory);
12967 NK_ASSERT(img_width);
12968 NK_ASSERT(img_height);
12969 NK_ASSERT(texture_data_mask);
12971 if (!img_memory || !img_width || !img_height || !texture_data_mask)
12974 pixels = (
nk_byte*)img_memory;
12975 for (y = 0, n = 0; y < tex_height; ++y) {
12976 for (x = 0; x < tex_width; ++x, ++n) {
12977 const int off0 = ((img_dst.
x + x) + (img_dst.
y + y) * img_width);
12978 const int off1 = off0 + 1 + tex_width;
12979 pixels[off0] = (texture_data_mask[n] == white) ? 0xFF : 0x00;
12980 pixels[off1] = (texture_data_mask[n] == black) ? 0xFF : 0x00;
12985 nk_font_bake_convert(
void *out_memory,
int img_width,
int img_height,
12986 const void *in_memory)
12992 NK_ASSERT(out_memory);
12993 NK_ASSERT(in_memory);
12994 NK_ASSERT(img_width);
12995 NK_ASSERT(img_height);
12996 if (!out_memory || !in_memory || !img_height || !img_width)
return;
12999 src = (
const nk_byte*)in_memory;
13000 for (n = (
int)(img_width * img_height); n > 0; n--)
13001 *dst++ = ((
nk_rune)(*src++) << 24) | 0x00FFFFFF;
13010 nk_font_text_width(
nk_handle handle,
float height,
const char *text,
int len)
13014 float text_width = 0;
13018 struct nk_font *font = (
struct nk_font*)handle.
ptr;
13020 NK_ASSERT(font->glyphs);
13021 if (!font || !text || !len)
13024 scale = height/font->info.height;
13025 glyph_len = text_len =
nk_utf_decode(text, &unicode, (
int)len);
13026 if (!glyph_len)
return 0;
13027 while (text_len <= (
int)len && glyph_len) {
13028 const struct nk_font_glyph *g;
13032 g = nk_font_find_glyph(font, unicode);
13033 text_width += g->xadvance * scale;
13036 glyph_len =
nk_utf_decode(text + text_len, &unicode, (
int)len - text_len);
13037 text_len += glyph_len;
13041 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
13043 nk_font_query_font_glyph(
nk_handle handle,
float height,
13044 struct nk_user_font_glyph *glyph,
nk_rune codepoint,
nk_rune next_codepoint)
13047 const struct nk_font_glyph *g;
13048 struct nk_font *font;
13053 font = (
struct nk_font*)handle.
ptr;
13055 NK_ASSERT(font->glyphs);
13056 if (!font || !glyph)
13059 scale = height/font->info.height;
13060 g = nk_font_find_glyph(font, codepoint);
13061 glyph->width = (g->x1 - g->x0) * scale;
13062 glyph->height = (g->y1 - g->y0) * scale;
13063 glyph->offset =
nk_vec2(g->x0 * scale, g->y0 * scale);
13064 glyph->xadvance = (g->xadvance * scale);
13065 glyph->uv[0] =
nk_vec2(g->u0, g->v0);
13066 glyph->uv[1] =
nk_vec2(g->u1, g->v1);
13069 NK_API const struct nk_font_glyph*
13070 nk_font_find_glyph(
struct nk_font *font,
nk_rune unicode)
13074 int total_glyphs = 0;
13075 const struct nk_font_glyph *glyph = 0;
13076 const struct nk_font_config *iter = 0;
13079 NK_ASSERT(font->glyphs);
13080 NK_ASSERT(font->info.ranges);
13081 if (!font || !font->glyphs)
return 0;
13083 glyph = font->fallback;
13084 iter = font->config;
13085 do {count = nk_range_count(iter->range);
13086 for (i = 0; i < count; ++i) {
13087 nk_rune f = iter->range[(i*2)+0];
13088 nk_rune t = iter->range[(i*2)+1];
13089 int diff = (int)((t - f) + 1);
13090 if (unicode >= f && unicode <= t)
13091 return &font->glyphs[((
nk_rune)total_glyphs + (unicode - f))];
13092 total_glyphs += diff;
13094 }
while ((iter = iter->n) != font->config);
13098 nk_font_init(
struct nk_font *font,
float pixel_height,
13099 nk_rune fallback_codepoint,
struct nk_font_glyph *glyphs,
13100 const struct nk_baked_font *baked_font,
nk_handle atlas)
13102 struct nk_baked_font baked;
13105 NK_ASSERT(baked_font);
13106 if (!font || !glyphs || !baked_font)
13109 baked = *baked_font;
13110 font->fallback = 0;
13111 font->info = baked;
13112 font->scale = (float)pixel_height / (
float)font->info.height;
13113 font->glyphs = &glyphs[baked_font->glyph_offset];
13114 font->texture = atlas;
13115 font->fallback_codepoint = fallback_codepoint;
13116 font->fallback = nk_font_find_glyph(font, fallback_codepoint);
13118 font->handle.height = font->info.height * font->scale;
13119 font->handle.width = nk_font_text_width;
13120 font->handle.userdata.ptr = font;
13121 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
13122 font->handle.query = nk_font_query_font_glyph;
13123 font->handle.texture = font->texture;
13137 #pragma clang diagnostic push
13138 #pragma clang diagnostic ignored "-Woverlength-strings"
13139 #elif defined(__GNUC__) || defined(__GNUG__)
13140 #pragma GCC diagnostic push
13141 #pragma GCC diagnostic ignored "-Woverlength-strings"
13144 #ifdef NK_INCLUDE_DEFAULT_FONT
13146 NK_GLOBAL const char nk_proggy_clean_ttf_compressed_data_base85[11980+1] =
13147 "7])#######hV0qs'/###[),##/l:$#Q6>##5[n42>c-TH`->>#/e>11NNV=Bv(*:.F?uu#(gRU.o0XGH`$vhLG1hxt9?W`#,5LsCp#-i>.r$<$6pD>Lb';9Crc6tgXmKVeU2cD4Eo3R/"
13148 "2*>]b(MC;$jPfY.;h^`IWM9<Lh2TlS+f-s$o6Q<BWH`YiU.xfLq$N;$0iR/GX:U(jcW2p/W*q?-qmnUCI;jHSAiFWM.R*kU@C=GH?a9wp8f$e.-4^Qg1)Q-GL(lf(r/7GrRgwV%MS=C#"
13149 "`8ND>Qo#t'X#(v#Y9w0#1D$CIf;W'#pWUPXOuxXuU(H9M(1<q-UE31#^-V'8IRUo7Qf./L>=Ke$$'5F%)]0^#0X@U.a<r:QLtFsLcL6##lOj)#.Y5<-R&KgLwqJfLgN&;Q?gI^#DY2uL"
13150 "i@^rMl9t=cWq6##weg>$FBjVQTSDgEKnIS7EM9>ZY9w0#L;>>#Mx&4Mvt//L[MkA#W@lK.N'[0#7RL_&#w+F%HtG9M#XL`N&.,GM4Pg;-<nLENhvx>-VsM.M0rJfLH2eTM`*oJMHRC`N"
13151 "kfimM2J,W-jXS:)r0wK#@Fge$U>`w'N7G#$#fB#$E^$#:9:hk+eOe--6x)F7*E%?76%^GMHePW-Z5l'&GiF#$956:rS?dA#fiK:)Yr+`�j@'DbG&#^$PG.Ll+DNa<XCMKEV*N)LN/N"
13152 "*b=%Q6pia-Xg8I$<MR&,VdJe$<(7G;Ckl'&hF;;$<_=X(b.RS%%)###MPBuuE1V:v&cXm#(&cV]`k9OhLMbn%s$G2,B$BfD3X*sp5#l,$R#]x_X1xKX%b5U*[r5iMfUo9U`N99hG)"
13153 "tm+/Us9pG)XPu`<0s-)WTt(gCRxIg(%6sfh=ktMKn3j)<6<b5Sk_/0(^]AaN#(p/L>&VZ>1i%h1S9u5o@YaaW$e+b<TWFn/Z:Oh(Cx2$lNEoN^e)#CFY@@I;BOQ*sRwZtZxRcU7uW6CX"
13154 "ow0i(?$Q[cjOd[P4d)]>ROPOpxTO7Stwi1::iB1q)C_=dV26J;2,]7op$]uQr@_V7$q^%lQwtuHY]=DX,n3L#0PHDO4f9>dC@O>HBuKPpP*E,N+b3L#lpR/MrTEH.IAQk.a>D[.e;mc."
13155 "x]Ip.PH^'/aqUO/$1WxLoW0[iLA<QT;5HKD+@qQ'NQ(3_PLhE48R.qAPSwQ0/WK?Z,[x?-J;jQTWA0X@KJ(_Y8N-:/M74:/-ZpKrUss?d#dZq]DAbkU*JqkL+nwX@@47`5>w=4h(9.`G"
13156 "CRUxHPeR`5Mjol(dUWxZa(>STrPkrJiWx`5U7F#.g*jrohGg`cg:lSTvEY/EV_7H4Q9[Z%cnv;JQYZ5q.l7Zeas:HOIZOB?G<Nald$qs]@]L<J7bR*>gv:[7MI2k).'2($5FNP&EQ(,)"
13157 "U]W]+fh18.vsai00);D3@4ku5P?DP8aJt+;qUM]=+b'8@;mViBKx0DE[-auGl8:PJ&Dj+M6OC]O^((##]`0i)drT;-7X`=-H3[igUnPG-NZlo.#k@h#=Ork$m>a>$-?Tm$UV(?#P6YY#"
13158 "'/###xe7q.73rI3*pP/$1>s9)W,JrM7SN]'/4C#v$U`0#V.[0>xQsH$fEmPMgY2u7Kh(G%siIfLSoS+MK2eTM$=5,M8p`A.;_R%#u[K#$x4AG8.kK/HSB==-'Ie/QTtG?-.*^N-4B/ZM"
13159 "_3YlQC7(p7q)&](`6_c)$/*JL(L-^(]$wIM`dPtOdGA,U3:w2M-0<q-]L_?^)1vw'.,MRsqVr.L;aN&#/EgJ)PBc[-f>+WomX2u7lqM2iEumMTcsF?-aT=Z-97UEnXglEn1K-bnEO`gu"
13160 "Ft(c%=;Am_Qs@jLooI&NX;]0#j4#F14;gl8-GQpgwhrq8'=l_f-b49'UOqkLu7-##oDY2L(te+Mch&gLYtJ,MEtJfLh'x'M=$CS-ZZ%P]8bZ>#S?YY#%Q&q'3^Fw&?D)UDNrocM3A76/"
13161 "/oL?#h7gl85[qW/NDOk%16ij;+:1a'iNIdb-ou8.P*w,v5#EI$TWS>Pot-R*H'-SEpA:g)f+O$%%`kA#G=8RMmG1&O`>to8bC]T&$,n.LoO>29sp3dt-52U%VM#q7'DHpg+#Z9%H[K<L"
13162 "%a2E-grWVM3@2=-k22tL]4$##6We'8UJCKE[d_=%wI;'6X-GsLX4j^SgJ$##R*w,vP3wK#iiW&#*h^D&R?jp7+/u&#(AP##XU8c$fSYW-J95_-Dp[g9wcO&#M-h1OcJlc-*vpw0xUX&#"
13163 "OQFKNX@QI'IoPp7nb,QU//MQ&ZDkKP)X<WSVL(68uVl&#c'[0#(s1X&xm$Y%B7*K:eDA323j998GXbA#pwMs-jgD$9QISB-A_(aN4xoFM^@C58D0+Q+q3n0#3U1InDjF682-SjMXJK)("
13164 "h$hxua_K]ul92%'BOU&#BRRh-slg8KDlr:%L71Ka:.A;%YULjDPmL<LYs8i#XwJOYaKPKc1h:'9Ke,g)b),78=I39B;xiY$bgGw-&.Zi9InXDuYa%G*f2Bq7mn9^#p1vv%#(Wi-;/Z5h"
13165 "o;#2:;%d	v68C5g?ntX0X)pT`;%pB3q7mgGN)3%(P8nTd5L7GeA-GL@+%J3u2:(Yf>et`e;)f#Km8&+DC$I46>#Kr]]u-[=99tts1.qb#q72g1WJO81q+eN'03'eM>&1XxY-caEnO"
13166 "j%2n8)),?ILR5^.Ibn<-X-Mq7[a82Lq:F&#ce+S9wsCK*x`569E8ew'He]h:sI[2LM$[guka3ZRd6:t%IG:;$%YiJ:Nq=?eAw;/:nnDq0(CYcMpG)qLN4$##&J<j$UpK<Q4a1]MupW^-"
13167 "sj_$%[HK%'F####QRZJ::Y3EGl4'@%FkiAOg#p[##O`gukTfBHagL<LHw%q&OV0##F=6/:chIm0@eCP8X]:kFI%hl8hgO@RcBhS-@Qb$%+m=hPDLg*%K8ln(wcf3/'DW-$.lR?n[nCH-"
13168 "eXOONTJlh:.RYF%3'p6sq:UIMA945&^HFS87@$EP2iG<-lCO$%c`uKGD3rC$x0BL8aFn--`ke%#HMP'vh1/R&O_J9'um,.<tx[@%wsJk&bUT2`0uMv7gg#qp/ij.L56'hl;.s5CUrxjO"
13169 "M7-##.l+Au'A&O:-T72L]P`&=;ctp'XScX*rU.>-XTt,%OVU4)S1+R-#dg0/Nn?Ku1^0f$B*P:Rowwm-`0PKjYDDM'3]d39VZHEl4,.j']Pk-M.h^&:0FACm$maq-&sgw0t7/6(^xtk%"
13170 "LuH88Fj-ekm>GA#_>568x6(OFRl-IZp`&b,_P'$M<Jnq79VsJW/mWS*PUiq76;]/NM_>hLbxfc$mj`,O;&%W2m`Zh:/)Uetw:aJ%]K9h:TcF]u_-Sj9,VK3M.*'&0D[Ca]J9gp8,kAW]"
13171 "%(?A%R$f<->Zts'^kn=-^@c4%-pY6qI%J%1IGxfLU9CP8cbPlXv);C=b),<2mOvP8up,UVf3839acAWAW-W?#ao/^#%KYo8fRULNd2.>%m]UK:n%r$'sw]J;5pAoO_#2mO3n,'=H5(et"
13172 "Hg*`+RLgv>=4U8guD$I%D:W>-r5V*%j*W:Kvej.Lp$<M-SGZ':+Q_k+uvOSLiEo(<aD/K<CCc`'Lx>'?;++O'>()jLR-^u68PHm8ZFWe+ej8h:9r6L*0//c&iH&R8pRbA#Kjm%upV1g:"
13173 "a_#Ur7FuA#(tRh#.Y5K+@?3<-8m0$PEn;J:rh6?I6uG<-`wMU'ircp0LaE_OtlMb&1#6T.#FDKu#1Lw%u%+GM+X'e?YLfjM[VO0MbuFp7;>Q&#WIo)0@F%q7c#4XAXN-U&VB<HFF*qL("
13174 "$/V,;(kXZejWO`<[5?\?ewY(*9=%wDc;,u<'9t3W-(H1th3+G]ucQ]kLs7df($/*JL]@*t7Bu_G3_7mp7<iaQjO@.kLg;x3B0lqp7Hf,^Ze7-##@/c58Mo(3;knp0%)A7?-W+eI'o8)b<"
13175 "nKnw'Ho8C=Y>pqB>0ie&jhZ[?iLR@@_AvA-iQC(=ksRZRVp7`.=+NpBC%rh&3]R:8XDmE5^V8O(x<<aG/1N$#FX$0V5Y6x'aErI3I$7x%E`v<-BY,)%-?Psf*l?%C3.mM(=/M0:JxG'?"
13176 "7WhH%o'a<-80g0NBxoO(GH<dM]n.+%q@jH?f.UsJ2Ggs&4<-e47&Kl+f//9@`b+?.TeN_&B8Ss?v;^Trk;f#YvJkl&w$]>-+k?'(<S:68tq*WoDfZu';mM?8X[ma8W%*`-=;D.(nc7/;"
13177 ")g:T1=^J$&BRV(-lTmNB6xqB[@0*o.erM*<SWF]u2=st-*(6v>^](H.aREZSi,#1:[IXaZFOm<-ui#qUq2$##Ri;u75OK#(RtaW-K-F`S+cF]uN`-KMQ%rP/Xri.LRcB##=YL3BgM/3M"
13178 "D?@f&1'BW-)Ju<L25gl8uhVm1hL$##*8###'A3/LkKW+(^rWX?5W_8g)a(m&K8P>#bmmWCMkk&#TR`C,5d>g)F;t,4:@_l8G/5h4vUd%&%950:VXD'QdWoY-F$BtUwmfe$YqL'8(PWX("
13179 "P?^@Po3$##`MSs?DWBZ/S>+4%>fX,VWv/w'KD`LP5IbH;rTV>n3cEK8U#bX]l-/V+^lj3;vlMb&[5YQ8#pekX9JP3XUC72L,,?+Ni&co7ApnO*5NK,((W-i:$,kp'UDAO(G0Sq7MVjJs"
13180 "bIu)'Z,*[>br5fX^:FPAWr-m2KgL<LUN098kTF&#lvo58=/vjDo;.;)Ka*hLR#/k=rKbxuV`>Q_nN6'8uTGT5g)uLv:873UpTLgH+#FgpH'_o1780Ph8KmxQJ8#H72L4@768@Tm&Q"
13181 "h4CB/5OvmA&,Q&QbUoi$a_%3M01H)4x7I^&KQVgtFnV+;[Pc>[m4k//,]1?#`VY[Jr*3&&slRfLiVZJ:]?=K3Sw=[$=uRB?3xk48@aeg<Z'<$#4H)6,>e0jT6'N#(q%.O=?2S]u*(m<-"
13182 "V8J'(1)G][68hW$5'q[GC&5j`TE?m'esFGNRM)j,ffZ?-qx8;->g4t*:CIP/[Qap7/9'#(1sao7w-.qNUdkJ)tCF&#B^;xGvn2r9FEPFFFcL@.iFNkTve$m%#QvQS8U@)2Z+3K:AKM5i"
13183 "sZ88+dKQ)W6>J%CL<KE>`.d*(B`-n8D9oK<Up]c$X$(,)M8Zt7/[rdkqTgl-0cuGMv'?>-XV1q['-5k'cAZ69e;D_?$ZPP&s^+7])$*$#@QYi9,5P	r+$%CE=68>K8r0=dSC%%(@p7"
13184 ".m7jilQ02'0-VWAg<a/''3u.=4L$Y)6k/K:_[3=&jvL<L0C/2'v:^;-DIBW,B4E68:kZ;%?8(Q8BH=kO65BW?xSG&#@uU,DS*,?.+(o(#1vCS8#CHF>TlGW'b)Tq7VT9q^*^$$.:&N@@"
13185 "$&)WHtPm*5_rO0&e%K&#-30j(E4#'Zb.o/(Tpm$>K'f@[PvFl,hfINTNU6u'0pao7%XUp9]5.>%h`8_=VYbxuel.NTSsJfLacFu3B'lQSu/m6-Oqem8T+oE--$0a/k]uj9EwsG>%veR*"
13186 "hv^BFpQj:K'#SJ,sB-'#](j.Lg92rTw-*n%@/;39rrJF,l#qV%OrtBeC6/,;qB3ebNW[?,Hqj2L.1NP&GjUR=1D8QaS3Up&@*9wP?+lo7b?@%'k4`p0Z$22%K3+iCZj?XJN4Nm&+YF]u"
13187 "@-W$U%VEQ/,,>>#)D<h#`)h0:<Q6909ua+&VU%n2:cG3FJ-%@Bj-DgLr`Hw&HAKjKjseK</xKT*)B,N9X3]krc12t'pgTV(Lv-tL[xg_%=M_q7a^x?7Ubd>#%8cY#YZ?=,`Wdxu/ae&#"
13188 "w6)R89tI#6@s'(6Bf7a&?S=^ZI_kS&ai`&=tE72L_D,;^R)7[$s<Eh#c&)q.MXI%#v9ROa5FZO%sF7q7Nwb&#ptUJ:aqJe$Sl68%.D###EC><?-aF&#RNQv>o8lKN%5/$(vdfq7+ebA#"
13189 "u1p]ovUKW&Y%q]'>$1@-[xfn$7ZTp7mM,G,Ko7a&Gu%G[RMxJs[0MM%wci.LFDK)(<c`Q8N)jEIF*+?P2a8g%)$q]o2aH8C&<SibC/q,(e:v;-b#6[$NtDZ84Je2KNvB#$P5?tQ3nt(0"
13190 "d=j.LQf./Ll33+(;q3L-w=8dX$#WF&uIJ@-bfI>%:_i2B5CsR8&9Z&#=mPEnm0f`<&c)QL5uJ#%u%lJj+D-r;BoFDoS97h5g)E#o:&S4weDF,9^Hoe`h*L+_a*NrLW-1pG_&2UdB8"
13191 "6e%B/:=>)N4xeW.*wft-;$'58-ESqr<b?UI(_%@[P46>#U`'6AQ]m&6/`Z>#S?YY#Vc;r7U2&326d=w&H####?TZ`*4?&.MK?LP8Vxg>$[QXc%QJv92.(Db*B)gb*BM9dM*hJMAo*c&#"
13192 "b0v=Pjer]$gG&JXDf->'StvU7505l9$AFvgYRI^&<^b68?j#q9QX4SM'RO#&sL1IM.rJfLUAj221]d##DW=m83u5;'bYx,*Sl0hL(W;;$doB&O/TQ:(Z^xBdLjL<Lni;''X.`$#8+1GD"
13193 ":k$YUWsbn8ogh6rxZ2Z9]%nd+>V#*8U_72Lh+2Q8Cj0i:6hp&$C/:p(HK>T8Y[gHQ4`4)'$Ab(Nof%V'8hL&#<NEdtg(n'=S1A(Q1/I&4([%dM`,Iu'1:_hL>SfD07&6D<fp8dHM7/g+"
13194 "tlPN9J*rKaPct&?'uBCem^jn%9_K)<,C5K3s=5g&GmJb*[SYq7K;TRLGCsM-$$;S%:Y@r7AK0pprpL<Lrh,q7e/%KWK:50I^+m'vi`3?%Zp+<-d+$L-Sv:@.o19n$s0&39;kn;S%BSq*"
13195 "$3WoJSCLweV[aZ'MQIjO<7;X-X;&+dMLvu#^UsGEC9WEc[X(wI7#2.(F0jV*eZf<-Qv3J-c+J5AlrB#$p(H68LvEA'q3n0#m,[`*8Ft)FcYgEud]CWfm68,(aLA$@EFTgLXoBq/UPlp7"
13196 ":d[/;r_ix=:TF`S5H-b<LI&HY(K=h#)]Lk$K14lVfm:x$H<3^Ql<M`$OhapBnkup'D#L$Pb_`N*g]2e;X/Dtg,bsj&K#2[-:iYr'_wgH)NUIR8a1n#S?Yej'h8^58UbZd+^FKD*T@;6A"
13197 "7aQC[K8d-(v6GI$x:T<&'Gp5Uf>@M.*J:;$-rv29'M]8qMv-tLp,'886iaC=Hb*YJoKJ,(j%K=H`K.v9HggqBIiZu'QvBT.#=)0ukruV&.)3=(^1`o*Pj4<-<aN((^7('#Z0wK#5GX@7"
13198 "u][`*S^43933A4rl][`*O4CgLEl]v$1Q3AeF37dbXk,.)vj#x'd`;qgbQR%FW,2(?LO=s%Sc68%NP'##Aotl8x=BE#j1UD([3$M(]UI2LX3RpKN@;/#f'f/&_mt&F)XdF<9t4)Qa.*kT"
13199 "LwQ'(TTB9.xH'>#MJ+gLq9-##@HuZPN0]u:h7.T..G:;$/Usj(T7`Q8tT72LnYl<-qx8;-HV7Q-&Xdx%1a,hC=0u+HlsV>nuIQL-5<N?)NBS)QN*_I,?&)2'IM%L3I)X((e/dl2&8'<M"
13200 ":^#M*Q+[T.Xri.LYS3v%fF`68h;b-X[/En'CR.q7E)p'/kle2HM,u;^%OKC-N+Ll%F9CF<Nf'^#t2L,;27W:0O@6##U6W7:$rJfLWHj$#)woqBefIZ.PK<b*t7ed;p*_m;4ExK#h@&]>"
13201 "_>@kXQtMacfD.m-VAb8;IReM3$wf0''hra*so568'Ip&vRs849'MRYSp%:t:h5qSgwpEr$B>Q,;s(C#$)`svQuF$##-D,##,g68@2[T;.XSdN9Qe)rpt._K-#5wF)sP'##p#C0c%-Gb%"
13202 "hd+<-j'Ai*x&&HMkT]C'OSl##5RG[JXaHN;d'uA#x._U;.`PU@(Z3dt4r152@:v,'R.Sj'w#0<-;kPI)FfJ&#AYJ&#//)>-k=m=*XnK$>=)72L]0I%>.G690a:$##<,);?;72#?x9+d;"
13203 "^V'9;jY@;)br#q^YQpx:X#Te$Z^'=-=bGhLf:D6&bNwZ9-ZD#n^9HhLMr5G;']d&6'wYmTFmL<LD)F^%[tC'8;+9E#C$g%#5Y>q9wI>P(9mI[>kC-ekLC/R&CH+s'B;K-M6$EB%is00:"
13204 "+A4[7xks.LrNk0&E)wILYF@2L'0Nb$+pv<(2.768/FrY&h$^3i&@+G%JT'<-,v`3;_)I9M^AE]CN?Cl2AZg+%4iTpT3<n-&%H%b<FDj2M<hH=&Eh<2Len$b*aTX=-8QxN)k11IM1c^j%"
13205 "9s<L<NFSo)B?+<-(GxsF,^-Eh@$4dXhN$+#rxK8'je'D7k`e;)2pYwPA'_p9&@^18ml1^[@g4t*[JOa*[=Qp7(qJ_oOL^('7fB&Hq-:sf,sNj8xq^>$U4O]GKx'm9)b@p7YsvK3w^YR-"
13206 "CdQ*:Ir<($u&)#(&?L9Rg3H)4fiEp^iI9O8KnTj,]H?D*r7'M;PwZ9K0E^k&-cpI;.p/6_vwoFMV<->#%Xi.LxVnrU(4&8/P+:hLSKj$#U%]49t'I:rgMi'FL@a:0Y-uA[39',(vbma*"
13207 "hU%<-SRF`Tt:542R_VV$p@[p8DV[A,?1839FWdF<TddF<9Ah-6&9tWoDlh]&1SpGMq>Ti1O*H&#(AL8[_P%.M>v^-))qOT*F5Cq0`Ye%+$B6i:7@0IX<N+T+0MlMBPQ*Vj>SsD<U4JHY"
13208 "8kD2)2fU/M#$e.)T4,_=8hLim[&);?UkK'-x?'(:siIfL<$pFM`i<?%W(mGDHM%>iWP,##P`%/L<eXi:@Z9C.7o=@(pXdAO/NLQ8lPl+HPOQa8wD8=^GlPa8TKI1CjhsCTSLJM'/Wl>-"
13209 "S(qw%sf/@%#B6;/U7K]uZbi^Oc^2n<bhPmUkMw>%t<)'mEVE''n`WnJra$^TKvX5B>;_aSEK',(hwa0:i4G?.Bci.(X[?b*($,=-n<.Q%`(X=?+@Am*Js0&=3bh8K]mL<LoNs'6,'85`"
13210 "0?t/'_U59@]ddF<#LdF<eWdF<OuN/45rY<-L@&#+fm>69=Lb,OcZV/);TTm8VI;?%OtJ<(b4mq7M6:u?KRdF<gR@2L=FNU-<b[(9c/ML3m;Z[$oF3g)GAWqpARc=<ROu7cL5l;-[A]%/"
13211 "+fsd;l#SafT/f*W]0=O'$(Tb<[)*@e775R-:Yob%g*>l*:xP?Yb.5)%w_I?7uk5JC+FS(m#i'k.'a0i)9<7b'fs'59hq$*5Uhv##pi^8+hIEBF`nvo`;'l0.^S1<-wUK2/Coh58KKhLj"
13212 "M=SO*rfO`+qC`W-On.=AJ56>>i2@2LH6A:&5q`?9I3@@'04&p2/LVa*T-4<-i3;M9UvZd+N7>b*eIwg:CC)c<>nO&#<IGe;__.thjZl<%w(Wk2xmp4Q@I#I9,DF]u7-P=.-_:YJ]aS@V"
13213 "?6*C()dOp7:WL,b&3Rg/.cmM9&r^>$(>.Z-I&J(Q0Hd5Q%7Co-b`-c<N(6r@ip+AurK<m86QIth*#v;-OBqi+L7wDE-Ir8K['m+DDSLwK&/.?-V%U_%3:qKNu$_b*B-kp7NaD'QdWQPK"
13214 "Yq[@>P)hI;*_F]u`Rb[.j8_Q/<&>uu+VsH$sM9TA%?)(vmJ80),P7E>)tjD%2L=-t#fK[%`v=Q8<FfNkgg^oIbah*#8/Qt$F&:K*-(N/'+1vMB,u()-a.VUU*#[e%gAAO(S>WlA2);Sa"
13215 ">gXm8YB`1d@K#n]76-a$U,mF<fX]idqd)<3,]J7JmW4`6]uks=4-72L(jEk+:bJ0M^q-8Dm_Z?0olP1C9Sa&H[d&c$ooQUj]Exd*3ZM@-WGW2%s',B-_M%>%Ul:#/'xoFM9QX-$.QN'>"
13216 "[%$Z$uF6pA6Ki2O5:8w*vP1<-1`[G,)-m#>0`P&#eb#.3i)rtB61(o'$?X3B</R90;eZ]%Ncq;-Tl]#F>2Qft^ae_5tKL9MUe9b*sLEQ95C&`=G?@Mj=wh*'3E>=-<)Gt*Iw)'QG:`@I"
13217 "wOf7&]1i'S01B+Ev/Nac#9S;=;YQpg_6U`*kVY39xK,[/6Aj7:'1Bm-_1EYfa1+o&o4hp7KN_Q(OlIo@S%;jVdn0'1<Vc52=u`3^o-n1'g4v58Hj&6_t7$##?M)c<$bgQ_'SY((-xkA#"
13218 "Y(,p'H9rIVY-b,'%bCPF7.J<Up^,(dU1VY*5#WkTU>h19w,WQhLI)3S#f$2(eb,jr*b;3Vw]*7NH%$c4Vs,eD9>XW8?N]o+(*pgC%/72LV-u<Hp,3@e^9UB1J+ak9-TN/mhKPg+AJYd$"
13219 "MlvAF_jCK*.O-^(63adMT->W%iewS8W6m2rtCpo'RS1R84=@paTKt)>=%&1[)*vp'u+x,VrwN;&]kuO9JDbg=pO$J*.jVe;u'm0dr9l,<*wMK*Oe=g8lV_KEBFkO'oU]^=[-792#ok,)"
13220 "i]lR8qQ2oA8wcRCZ^7w/Njh;?.stX?Q1>S1q4Bn$)K1<-rGdO'$Wr.Lc.CG)$/*JL4tNR/,SVO3,aUw'DJN:)Ss;wGn9A32ijw%FL+Z0Fn.U9;reSq)bmI32U==5ALuG&#Vf1398/pVo"
13221 "1*c-(aY168o<`JsSbk-,1N;$>0:OUas(3:8Z972LSfF8eb=c-;>SPw7.6hn3m`9^Xkn(r.qS[0;T%&Qc=+STRxX'q1BNk3&*eu2;&8q$&x>Q#Q7^Tf+6<(d%ZVmj2bDi%.3L2n+4W'$P"
13222 "iDDG)g,r%+?,$@?uou5tSe2aN_AQU*<h`e-GI7)?OK2A.d7_c)?wQ5AS@DL3r#7fSkgl6-++D:'A,uq7SvlB$pcpH'q3n0#_%dY#xCpr-l<F0NR@-##FEV6NTF6##$l84N1w?AO>'IAO"
13223 "URQ##V^Fv-XFbGM7Fl(N<3DhLGF%q.1rC$#:T__&Pi68%0xi_&[qFJ(77j_&JWoF.V735&T,[R*:xFR*K5>>#`bW-?4Ne_&6Ne_&6Ne_&n`kr-#GJcM6X;uM6X;uM(.a..^2TkL%oR(#"
13224 ";u.T%fAr%4tJ8&><1=GHZ_+m9/#H1F^R#SC#*N=BA9(D?v[UiFY>>^8p,KKF.W]L29uLkLlu/+4T<XoIB&hx=T1PcDaB&;HH+-AFr?(m9HZV)FKS8JCw;SD=6[^/DZUL`EUDf]GGlG&>"
13225 "w$)F./^n3+rlo+DB;5sIYGNk+i1t-69Jg--0pao7Sm#K)pdHW&;LuDNH@H>#/X-TI(;P>#,Gc>#0Su>#4`1?#8lC?#<xU?#@.i?#D:%@#HF7@#LRI@#P_[@#Tkn@#Xw*A#]-=A#a9OA#"
13226 "d<F&#*;G##.GY##2Sl##6`($#:l:$#>xL$#B.`$#F:r$#JF.%#NR@%#R_R%#Vke%#Zww%#_-4^Rh%Sflr-k'MS.o?.5/sWel/wpEM0%3'/1)K^f1-d>G21&v(35>V`39V7A4=onx4"
13227 "A1OY5EI0;6Ibgr6M$HS7Q<)58C5w,;WoA*#[%T*#`1g*#d=#+#hI5+#lUG+#pbY+#tnl+#x$),#&1;,#*=M,#.I`,#2Ur,#6b.-#;w[H#iQtA#m^0B#qjBB#uvTB##-hB#'9$C#+E6C#"
13228 "/QHC#3^ZC#7jmC#;v)D#?,<D#C8ND#GDaD#KPsD#O]/E#g1A5#KA*1#gC17#MGd;#8(02#L-d3#rWM4#Hga1#,<w0#T.j<#O#'2#CYN1#qa^:#_4m3#o@/=#eG8=#t8J5#`+78#4uI-#"
13229 "m3B2#SB[8#Q0@8#i[*9#iOn8#1Nm;#^sN9#qh<9#:=x-#P;K2#$%X9#bC+.#Rg;<#mN=.#MTF.#RZO.#2?)4#Y#(/#[)1/#b;L/#dAU/#0Sv;#lY$0#n`-0#sf60#(F24#wrH0#%/e0#"
13230 "TmD<#%JSMFove:CTBEXI:<eh2g)B,3h2^G3i;#d3jD>)4kMYD4lVu`4m`:&5niUA5@(A5BA1]PBB:xlBCC=2CDLXMCEUtiCf&0g2'tN?PGT4CPGT4CPGT4CPGT4CPGT4CPGT4CPGT4CP"
13231 "GT4CPGT4CPGT4CPGT4CPGT4CPGT4CP-qekC`.9kEg^+F$kwViFJTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5o,^<-28ZI'O?;xp"
13232 "O?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xp;7q-#lLYI:xvD=#";
13236 #define NK_CURSOR_DATA_W 90
13237 #define NK_CURSOR_DATA_H 27
13238 NK_GLOBAL const char nk_custom_cursor_data[NK_CURSOR_DATA_W * NK_CURSOR_DATA_H + 1] =
13240 "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX"
13241 "..- -X.....X- X.X - X.X -X.....X - X.....X"
13242 "--- -XXX.XXX- X...X - X...X -X....X - X....X"
13243 "X - X.X - X.....X - X.....X -X...X - X...X"
13244 "XX - X.X -X.......X- X.......X -X..X.X - X.X..X"
13245 "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X"
13246 "X..X - X.X - X.X - X.X -XX X.X - X.X XX"
13247 "X...X - X.X - X.X - XX X.X XX - X.X - X.X "
13248 "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X "
13249 "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X "
13250 "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X "
13251 "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X "
13252 "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X "
13253 "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X "
13254 "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X "
13255 "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X "
13256 "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX "
13257 "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------"
13258 "X.X X..X - -X.......X- X.......X - XX XX - "
13259 "XX X..X - - X.....X - X.....X - X.X X.X - "
13260 " X..X - X...X - X...X - X..X X..X - "
13261 " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - "
13262 "------------ - X - X -X.....................X- "
13263 " ----------------------------------- X...XXXXXXXXXXXXX...X - "
13270 #pragma clang diagnostic pop
13271 #elif defined(__GNUC__) || defined(__GNUG__)
13272 #pragma GCC diagnostic pop
13282 nk_decompress_length(
unsigned char *input)
13284 return (
unsigned int)((input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]);
13287 nk__match(
unsigned char *data,
unsigned int length)
13290 NK_ASSERT (nk__dout + length <= nk__barrier);
13291 if (nk__dout + length > nk__barrier) { nk__dout += length;
return; }
13292 if (data < nk__barrier4) { nk__dout = nk__barrier+1;
return; }
13293 while (length--) *nk__dout++ = *data++;
13296 nk__lit(
unsigned char *data,
unsigned int length)
13298 NK_ASSERT (nk__dout + length <= nk__barrier);
13299 if (nk__dout + length > nk__barrier) { nk__dout += length;
return; }
13300 if (data < nk__barrier2) { nk__dout = nk__barrier+1;
return; }
13301 NK_MEMCPY(nk__dout, data, length);
13302 nk__dout += length;
13305 nk_decompress_token(
unsigned char *i)
13307 #define nk__in2(x) ((i[x] << 8) + i[(x)+1])
13308 #define nk__in3(x) ((i[x] << 16) + nk__in2((x)+1))
13309 #define nk__in4(x) ((i[x] << 24) + nk__in3((x)+1))
13312 if (*i >= 0x80) nk__match(nk__dout-i[1]-1, (
unsigned int)i[0] - 0x80 + 1), i += 2;
13313 else if (*i >= 0x40) nk__match(nk__dout-(nk__in2(0) - 0x4000 + 1), (
unsigned int)i[2]+1), i += 3;
13314 else nk__lit(i+1, (
unsigned int)i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1);
13316 if (*i >= 0x18) nk__match(nk__dout-(
unsigned int)(nk__in3(0) - 0x180000 + 1), (
unsigned int)i[3]+1), i += 4;
13317 else if (*i >= 0x10) nk__match(nk__dout-(
unsigned int)(nk__in3(0) - 0x100000 + 1), (
unsigned int)nk__in2(3)+1), i += 5;
13318 else if (*i >= 0x08) nk__lit(i+2, (
unsigned int)nk__in2(0) - 0x0800 + 1), i += 2 + (nk__in2(0) - 0x0800 + 1);
13319 else if (*i == 0x07) nk__lit(i+3, (
unsigned int)nk__in2(1) + 1), i += 3 + (nk__in2(1) + 1);
13320 else if (*i == 0x06) nk__match(nk__dout-(
unsigned int)(nk__in3(1)+1), i[4]+1u), i += 5;
13321 else if (*i == 0x04) nk__match(nk__dout-(
unsigned int)(nk__in3(1)+1), (
unsigned int)nk__in2(4)+1u), i += 6;
13326 nk_adler32(
unsigned int adler32,
unsigned char *buffer,
unsigned int buflen)
13328 const unsigned long ADLER_MOD = 65521;
13329 unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16;
13330 unsigned long blocklen, i;
13332 blocklen = buflen % 5552;
13334 for (i=0; i + 7 < blocklen; i += 8) {
13335 s1 += buffer[0]; s2 += s1;
13336 s1 += buffer[1]; s2 += s1;
13337 s1 += buffer[2]; s2 += s1;
13338 s1 += buffer[3]; s2 += s1;
13339 s1 += buffer[4]; s2 += s1;
13340 s1 += buffer[5]; s2 += s1;
13341 s1 += buffer[6]; s2 += s1;
13342 s1 += buffer[7]; s2 += s1;
13345 for (; i < blocklen; ++i) {
13346 s1 += *buffer++; s2 += s1;
13349 s1 %= ADLER_MOD; s2 %= ADLER_MOD;
13350 buflen -= (
unsigned int)blocklen;
13353 return (
unsigned int)(s2 << 16) + (
unsigned int)s1;
13356 nk_decompress(
unsigned char *output,
unsigned char *i,
unsigned int length)
13359 if (nk__in4(0) != 0x57bC0000)
return 0;
13360 if (nk__in4(4) != 0)
return 0;
13361 olen = nk_decompress_length(i);
13363 nk__barrier3 = i+length;
13364 nk__barrier = output + olen;
13365 nk__barrier4 = output;
13370 unsigned char *old_i = i;
13371 i = nk_decompress_token(i);
13373 if (*i == 0x05 && i[1] == 0xfa) {
13374 NK_ASSERT(nk__dout == output + olen);
13375 if (nk__dout != output + olen)
return 0;
13376 if (nk_adler32(1, output, olen) != (
unsigned int) nk__in4(2))
13384 NK_ASSERT(nk__dout <= output + olen);
13385 if (nk__dout > output + olen)
13390 nk_decode_85_byte(
char c)
13392 return (
unsigned int)((c >=
'\\') ? c-36 : c-35);
13395 nk_decode_85(
unsigned char* dst,
const unsigned char* src)
13400 nk_decode_85_byte((
char)src[0]) +
13401 85 * (nk_decode_85_byte((
char)src[1]) +
13402 85 * (nk_decode_85_byte((
char)src[2]) +
13403 85 * (nk_decode_85_byte((
char)src[3]) +
13404 85 * nk_decode_85_byte((
char)src[4]))));
13407 dst[0] = (
unsigned char)((tmp >> 0) & 0xFF);
13408 dst[1] = (
unsigned char)((tmp >> 8) & 0xFF);
13409 dst[2] = (
unsigned char)((tmp >> 16) & 0xFF);
13410 dst[3] = (
unsigned char)((tmp >> 24) & 0xFF);
13422 NK_API struct nk_font_config
13423 nk_font_config(float pixel_height)
13425 struct nk_font_config cfg;
13429 cfg.ttf_data_owned_by_atlas = 0;
13430 cfg.size = pixel_height;
13431 cfg.oversample_h = 3;
13432 cfg.oversample_v = 1;
13433 cfg.pixel_snap = 0;
13434 cfg.coord_type = NK_COORD_UV;
13436 cfg.range = nk_font_default_glyph_ranges();
13437 cfg.merge_mode = 0;
13438 cfg.fallback_glyph =
'?';
13443 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
13445 nk_font_atlas_init_default(
struct nk_font_atlas *atlas)
13448 if (!atlas)
return;
13450 atlas->temporary.userdata.ptr = 0;
13451 atlas->temporary.alloc = nk_malloc;
13452 atlas->temporary.free = nk_mfree;
13453 atlas->permanent.userdata.ptr = 0;
13454 atlas->permanent.alloc = nk_malloc;
13455 atlas->permanent.free = nk_mfree;
13459 nk_font_atlas_init(
struct nk_font_atlas *atlas,
struct nk_allocator *alloc)
13463 if (!atlas || !alloc)
return;
13465 atlas->permanent = *alloc;
13466 atlas->temporary = *alloc;
13469 nk_font_atlas_init_custom(
struct nk_font_atlas *atlas,
13473 NK_ASSERT(permanent);
13474 NK_ASSERT(temporary);
13475 if (!atlas || !permanent || !temporary)
return;
13477 atlas->permanent = *permanent;
13478 atlas->temporary = *temporary;
13481 nk_font_atlas_begin(
struct nk_font_atlas *atlas)
13484 NK_ASSERT(atlas->temporary.alloc && atlas->temporary.free);
13485 NK_ASSERT(atlas->permanent.alloc && atlas->permanent.free);
13486 if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free ||
13487 !atlas->temporary.alloc || !atlas->temporary.free)
return;
13488 if (atlas->glyphs) {
13489 atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
13492 if (atlas->pixel) {
13493 atlas->permanent.free(atlas->permanent.userdata, atlas->pixel);
13498 nk_font_atlas_add(
struct nk_font_atlas *atlas,
const struct nk_font_config *config)
13500 struct nk_font *font = 0;
13501 struct nk_font_config *cfg;
13504 NK_ASSERT(atlas->permanent.alloc);
13505 NK_ASSERT(atlas->permanent.free);
13506 NK_ASSERT(atlas->temporary.alloc);
13507 NK_ASSERT(atlas->temporary.free);
13510 NK_ASSERT(config->ttf_blob);
13511 NK_ASSERT(config->ttf_size);
13512 NK_ASSERT(config->size > 0.0f);
13514 if (!atlas || !config || !config->ttf_blob || !config->ttf_size || config->size <= 0.0f||
13515 !atlas->permanent.alloc || !atlas->permanent.free ||
13516 !atlas->temporary.alloc || !atlas->temporary.free)
13520 cfg = (
struct nk_font_config*)
13521 atlas->permanent.alloc(atlas->permanent.userdata,0,
sizeof(
struct nk_font_config));
13522 NK_MEMCPY(cfg, config,
sizeof(*config));
13526 if (!config->merge_mode) {
13528 if (!atlas->config) {
13529 atlas->config = cfg;
13532 struct nk_font_config *i = atlas->config;
13533 while (i->next) i = i->next;
13538 font = (
struct nk_font*)
13539 atlas->permanent.alloc(atlas->permanent.userdata,0,
sizeof(
struct nk_font));
13541 nk_zero(font,
sizeof(*font));
13542 if (!font)
return 0;
13543 font->config = cfg;
13546 if (!atlas->fonts) {
13547 atlas->fonts = font;
13550 struct nk_font *i = atlas->fonts;
13551 while (i->next) i = i->next;
13555 cfg->font = &font->info;
13558 struct nk_font *f = 0;
13559 struct nk_font_config *c = 0;
13560 NK_ASSERT(atlas->font_num);
13563 cfg->font = &f->info;
13571 if (!config->ttf_data_owned_by_atlas) {
13572 cfg->ttf_blob = atlas->permanent.alloc(atlas->permanent.userdata,0, cfg->ttf_size);
13573 NK_ASSERT(cfg->ttf_blob);
13574 if (!cfg->ttf_blob) {
13578 NK_MEMCPY(cfg->ttf_blob, config->ttf_blob, cfg->ttf_size);
13579 cfg->ttf_data_owned_by_atlas = 1;
13585 nk_font_atlas_add_from_memory(
struct nk_font_atlas *atlas,
void *memory,
13586 nk_size size,
float height,
const struct nk_font_config *config)
13588 struct nk_font_config cfg;
13593 NK_ASSERT(atlas->temporary.alloc);
13594 NK_ASSERT(atlas->temporary.free);
13595 NK_ASSERT(atlas->permanent.alloc);
13596 NK_ASSERT(atlas->permanent.free);
13597 if (!atlas || !atlas->temporary.alloc || !atlas->temporary.free || !memory || !size ||
13598 !atlas->permanent.alloc || !atlas->permanent.free)
13601 cfg = (config) ? *config: nk_font_config(height);
13602 cfg.ttf_blob = memory;
13603 cfg.ttf_size = size;
13605 cfg.ttf_data_owned_by_atlas = 0;
13606 return nk_font_atlas_add(atlas, &cfg);
13608 #ifdef NK_INCLUDE_STANDARD_IO
13610 nk_font_atlas_add_from_file(
struct nk_font_atlas *atlas,
const char *file_path,
13611 float height,
const struct nk_font_config *config)
13615 struct nk_font_config cfg;
13618 NK_ASSERT(atlas->temporary.alloc);
13619 NK_ASSERT(atlas->temporary.free);
13620 NK_ASSERT(atlas->permanent.alloc);
13621 NK_ASSERT(atlas->permanent.free);
13623 if (!atlas || !file_path)
return 0;
13624 memory = nk_file_load(file_path, &size, &atlas->permanent);
13625 if (!memory)
return 0;
13627 cfg = (config) ? *config: nk_font_config(height);
13628 cfg.ttf_blob = memory;
13629 cfg.ttf_size = size;
13631 cfg.ttf_data_owned_by_atlas = 1;
13632 return nk_font_atlas_add(atlas, &cfg);
13636 nk_font_atlas_add_compressed(
struct nk_font_atlas *atlas,
13637 void *compressed_data,
nk_size compressed_size,
float height,
13638 const struct nk_font_config *config)
13640 unsigned int decompressed_size;
13641 void *decompressed_data;
13642 struct nk_font_config cfg;
13645 NK_ASSERT(atlas->temporary.alloc);
13646 NK_ASSERT(atlas->temporary.free);
13647 NK_ASSERT(atlas->permanent.alloc);
13648 NK_ASSERT(atlas->permanent.free);
13650 NK_ASSERT(compressed_data);
13651 NK_ASSERT(compressed_size);
13652 if (!atlas || !compressed_data || !atlas->temporary.alloc || !atlas->temporary.free ||
13653 !atlas->permanent.alloc || !atlas->permanent.free)
13656 decompressed_size = nk_decompress_length((
unsigned char*)compressed_data);
13657 decompressed_data = atlas->permanent.alloc(atlas->permanent.userdata,0,decompressed_size);
13658 NK_ASSERT(decompressed_data);
13659 if (!decompressed_data)
return 0;
13660 nk_decompress((
unsigned char*)decompressed_data, (
unsigned char*)compressed_data,
13661 (
unsigned int)compressed_size);
13663 cfg = (config) ? *config: nk_font_config(height);
13664 cfg.ttf_blob = decompressed_data;
13665 cfg.ttf_size = decompressed_size;
13667 cfg.ttf_data_owned_by_atlas = 1;
13668 return nk_font_atlas_add(atlas, &cfg);
13671 nk_font_atlas_add_compressed_base85(
struct nk_font_atlas *atlas,
13672 const char *data_base85,
float height,
const struct nk_font_config *config)
13674 int compressed_size;
13675 void *compressed_data;
13676 struct nk_font *font;
13679 NK_ASSERT(atlas->temporary.alloc);
13680 NK_ASSERT(atlas->temporary.free);
13681 NK_ASSERT(atlas->permanent.alloc);
13682 NK_ASSERT(atlas->permanent.free);
13684 NK_ASSERT(data_base85);
13685 if (!atlas || !data_base85 || !atlas->temporary.alloc || !atlas->temporary.free ||
13686 !atlas->permanent.alloc || !atlas->permanent.free)
13689 compressed_size = (((int)
nk_strlen(data_base85) + 4) / 5) * 4;
13690 compressed_data = atlas->temporary.alloc(atlas->temporary.userdata,0, (
nk_size)compressed_size);
13691 NK_ASSERT(compressed_data);
13692 if (!compressed_data)
return 0;
13693 nk_decode_85((
unsigned char*)compressed_data, (
const unsigned char*)data_base85);
13694 font = nk_font_atlas_add_compressed(atlas, compressed_data,
13695 (
nk_size)compressed_size, height, config);
13696 atlas->temporary.free(atlas->temporary.userdata, compressed_data);
13700 #ifdef NK_INCLUDE_DEFAULT_FONT
13702 nk_font_atlas_add_default(
struct nk_font_atlas *atlas,
13703 float pixel_height,
const struct nk_font_config *config)
13706 NK_ASSERT(atlas->temporary.alloc);
13707 NK_ASSERT(atlas->temporary.free);
13708 NK_ASSERT(atlas->permanent.alloc);
13709 NK_ASSERT(atlas->permanent.free);
13710 return nk_font_atlas_add_compressed_base85(atlas,
13711 nk_proggy_clean_ttf_compressed_data_base85, pixel_height, config);
13715 nk_font_atlas_bake(
struct nk_font_atlas *atlas,
int *width,
int *height,
13716 enum nk_font_atlas_format fmt)
13721 struct nk_font *font_iter;
13722 struct nk_font_baker *baker;
13725 NK_ASSERT(atlas->temporary.alloc);
13726 NK_ASSERT(atlas->temporary.free);
13727 NK_ASSERT(atlas->permanent.alloc);
13728 NK_ASSERT(atlas->permanent.free);
13732 if (!atlas || !width || !height ||
13733 !atlas->temporary.alloc || !atlas->temporary.free ||
13734 !atlas->permanent.alloc || !atlas->permanent.free)
13737 #ifdef NK_INCLUDE_DEFAULT_FONT
13739 if (!atlas->font_num)
13740 atlas->default_font = nk_font_atlas_add_default(atlas, 13.0f, 0);
13742 NK_ASSERT(atlas->font_num);
13743 if (!atlas->font_num)
return 0;
13746 nk_font_baker_memory(&tmp_size, &atlas->glyph_count, atlas->config, atlas->font_num);
13747 tmp = atlas->temporary.alloc(atlas->temporary.userdata,0, tmp_size);
13749 if (!tmp)
goto failed;
13752 baker = nk_font_baker(tmp, atlas->glyph_count, atlas->font_num, &atlas->temporary);
13753 atlas->glyphs = (
struct nk_font_glyph*)atlas->permanent.alloc(
13754 atlas->permanent.userdata,0,
sizeof(
struct nk_font_glyph)*(
nk_size)atlas->glyph_count);
13755 NK_ASSERT(atlas->glyphs);
13756 if (!atlas->glyphs)
13760 atlas->custom.w = (NK_CURSOR_DATA_W*2)+1;
13761 atlas->custom.h = NK_CURSOR_DATA_H + 1;
13762 if (!nk_font_bake_pack(baker, &img_size, width, height, &atlas->custom,
13763 atlas->config, atlas->font_num, &atlas->temporary))
13767 atlas->pixel = atlas->temporary.alloc(atlas->temporary.userdata,0, img_size);
13768 NK_ASSERT(atlas->pixel);
13773 nk_font_bake(baker, atlas->pixel, *width, *height,
13774 atlas->glyphs, atlas->glyph_count, atlas->config, atlas->font_num);
13775 nk_font_bake_custom_data(atlas->pixel, *width, *height, atlas->custom,
13776 nk_custom_cursor_data, NK_CURSOR_DATA_W, NK_CURSOR_DATA_H,
'.',
'X');
13778 if (fmt == NK_FONT_ATLAS_RGBA32) {
13780 void *img_rgba = atlas->temporary.alloc(atlas->temporary.userdata,0,
13781 (
nk_size)(*width * *height * 4));
13782 NK_ASSERT(img_rgba);
13783 if (!img_rgba)
goto failed;
13784 nk_font_bake_convert(img_rgba, *width, *height, atlas->pixel);
13785 atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
13786 atlas->pixel = img_rgba;
13788 atlas->tex_width = *width;
13789 atlas->tex_height = *height;
13792 for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
13793 struct nk_font *font = font_iter;
13794 struct nk_font_config *config = font->config;
13795 nk_font_init(font, config->size, config->fallback_glyph, atlas->glyphs,
13802 {{ 0, 3}, {12,19}, { 0, 0}},
13803 {{13, 0}, { 7,16}, { 4, 8}},
13804 {{31, 0}, {23,23}, {11,11}},
13805 {{21, 0}, { 9, 23}, { 5,11}},
13806 {{55,18}, {23, 9}, {11, 5}},
13807 {{73, 0}, {17,17}, { 9, 9}},
13808 {{55, 0}, {17,17}, { 9, 9}}
13811 struct nk_cursor *cursor = &atlas->cursors[i];
13812 cursor->
img.
w = (
unsigned short)*width;
13813 cursor->
img.
h = (
unsigned short)*height;
13814 cursor->
img.
region[0] = (
unsigned short)(atlas->custom.x + nk_cursor_data[i][0].x);
13815 cursor->
img.
region[1] = (
unsigned short)(atlas->custom.y + nk_cursor_data[i][0].y);
13816 cursor->
img.
region[2] = (
unsigned short)nk_cursor_data[i][1].x;
13817 cursor->
img.
region[3] = (
unsigned short)nk_cursor_data[i][1].y;
13818 cursor->size = nk_cursor_data[i][1];
13819 cursor->
offset = nk_cursor_data[i][2];
13822 atlas->temporary.free(atlas->temporary.userdata, tmp);
13823 return atlas->pixel;
13827 if (tmp) atlas->temporary.free(atlas->temporary.userdata, tmp);
13828 if (atlas->glyphs) {
13829 atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
13832 if (atlas->pixel) {
13833 atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
13839 nk_font_atlas_end(
struct nk_font_atlas *atlas,
nk_handle texture,
13843 struct nk_font *font_iter;
13847 null->texture = texture;
13848 null->uv =
nk_vec2(0.5f,0.5f);
13851 null->texture = texture;
13852 null->uv.x = (atlas->custom.x + 0.5f)/(
float)atlas->tex_width;
13853 null->uv.y = (atlas->custom.y + 0.5f)/(
float)atlas->tex_height;
13855 for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
13856 font_iter->texture = texture;
13857 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
13858 font_iter->handle.texture = texture;
13862 atlas->cursors[i].img.handle = texture;
13864 atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
13866 atlas->tex_width = 0;
13867 atlas->tex_height = 0;
13868 atlas->custom.x = 0;
13869 atlas->custom.y = 0;
13870 atlas->custom.w = 0;
13871 atlas->custom.h = 0;
13874 nk_font_atlas_cleanup(
struct nk_font_atlas *atlas)
13877 NK_ASSERT(atlas->temporary.alloc);
13878 NK_ASSERT(atlas->temporary.free);
13879 NK_ASSERT(atlas->permanent.alloc);
13880 NK_ASSERT(atlas->permanent.free);
13881 if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free)
return;
13882 if (atlas->config) {
13883 struct nk_font_config *iter;
13884 for (iter = atlas->config; iter; iter = iter->next) {
13885 struct nk_font_config *i;
13886 for (i = iter->n; i != iter; i = i->n) {
13887 atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
13890 atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
13891 iter->ttf_blob = 0;
13896 nk_font_atlas_clear(
struct nk_font_atlas *atlas)
13899 NK_ASSERT(atlas->temporary.alloc);
13900 NK_ASSERT(atlas->temporary.free);
13901 NK_ASSERT(atlas->permanent.alloc);
13902 NK_ASSERT(atlas->permanent.free);
13903 if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free)
return;
13905 if (atlas->config) {
13906 struct nk_font_config *iter, *next;
13907 for (iter = atlas->config; iter; iter = next) {
13908 struct nk_font_config *i, *n;
13909 for (i = iter->n; i != iter; i = n) {
13912 atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
13913 atlas->permanent.free(atlas->permanent.userdata, i);
13917 atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
13918 atlas->permanent.free(atlas->permanent.userdata, iter);
13922 if (atlas->fonts) {
13923 struct nk_font *iter, *next;
13924 for (iter = atlas->fonts; iter; iter = next) {
13926 atlas->permanent.free(atlas->permanent.userdata, iter);
13931 atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
13999 #ifdef NK_KEYSTATE_BASED_INPUT
14204 #define NK_COLOR_MAP(NK_COLOR)\
14205 NK_COLOR(NK_COLOR_TEXT, 175,175,175,255) \
14206 NK_COLOR(NK_COLOR_WINDOW, 45, 45, 45, 255) \
14207 NK_COLOR(NK_COLOR_HEADER, 40, 40, 40, 255) \
14208 NK_COLOR(NK_COLOR_BORDER, 65, 65, 65, 255) \
14209 NK_COLOR(NK_COLOR_BUTTON, 50, 50, 50, 255) \
14210 NK_COLOR(NK_COLOR_BUTTON_HOVER, 40, 40, 40, 255) \
14211 NK_COLOR(NK_COLOR_BUTTON_ACTIVE, 35, 35, 35, 255) \
14212 NK_COLOR(NK_COLOR_TOGGLE, 100,100,100,255) \
14213 NK_COLOR(NK_COLOR_TOGGLE_HOVER, 120,120,120,255) \
14214 NK_COLOR(NK_COLOR_TOGGLE_CURSOR, 45, 45, 45, 255) \
14215 NK_COLOR(NK_COLOR_SELECT, 45, 45, 45, 255) \
14216 NK_COLOR(NK_COLOR_SELECT_ACTIVE, 35, 35, 35,255) \
14217 NK_COLOR(NK_COLOR_SLIDER, 38, 38, 38, 255) \
14218 NK_COLOR(NK_COLOR_SLIDER_CURSOR, 100,100,100,255) \
14219 NK_COLOR(NK_COLOR_SLIDER_CURSOR_HOVER, 120,120,120,255) \
14220 NK_COLOR(NK_COLOR_SLIDER_CURSOR_ACTIVE, 150,150,150,255) \
14221 NK_COLOR(NK_COLOR_PROPERTY, 38, 38, 38, 255) \
14222 NK_COLOR(NK_COLOR_EDIT, 38, 38, 38, 255) \
14223 NK_COLOR(NK_COLOR_EDIT_CURSOR, 175,175,175,255) \
14224 NK_COLOR(NK_COLOR_COMBO, 45, 45, 45, 255) \
14225 NK_COLOR(NK_COLOR_CHART, 120,120,120,255) \
14226 NK_COLOR(NK_COLOR_CHART_COLOR, 45, 45, 45, 255) \
14227 NK_COLOR(NK_COLOR_CHART_COLOR_HIGHLIGHT, 255, 0, 0, 255) \
14228 NK_COLOR(NK_COLOR_SCROLLBAR, 40, 40, 40, 255) \
14229 NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR, 100,100,100,255) \
14230 NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_HOVER, 120,120,120,255) \
14231 NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_ACTIVE, 150,150,150,255) \
14232 NK_COLOR(NK_COLOR_TAB_HEADER, 40, 40, 40,255)
14236 #define NK_COLOR(a,b,c,d,e) {b,c,d,e},
14237 NK_COLOR_MAP(NK_COLOR)
14241 #define NK_COLOR(a,b,c,d,e) #a,
14242 NK_COLOR_MAP(NK_COLOR)
14249 return nk_color_names[c];
14256 i.data.image = img;
14264 i.data.color = col;
14272 i.data.color =
nk_rgba(0,0,0,0);
14296 table = (!table) ? nk_default_color_style: table;
14299 text = &style->
text;
14304 button = &style->
button;
14384 toggle = &style->
option;
14426 slider = &style->
slider;
14537 edit = &style->
edit;
14575 property->padding =
nk_vec2(4,4);
14576 property->border = 1;
14577 property->rounding = 10;
14578 property->draw_begin = 0;
14579 property->draw_end = 0;
14626 chart = &style->
chart;
14637 combo = &style->
combo;
14835 struct nk_config_stack_user_font *font_stack;
14836 struct nk_config_stack_user_font_element *element;
14839 if (!
ctx)
return 0;
14842 NK_ASSERT(font_stack->head < (
int)
NK_LEN(font_stack->elements));
14843 if (font_stack->head >= (
int)
NK_LEN(font_stack->elements))
14846 element = &font_stack->elements[font_stack->head++];
14855 struct nk_config_stack_user_font *font_stack;
14856 struct nk_config_stack_user_font_element *element;
14859 if (!
ctx)
return 0;
14862 NK_ASSERT(font_stack->head > 0);
14863 if (font_stack->head < 1)
14866 element = &font_stack->elements[--font_stack->head];
14867 *element->address = element->old_value;
14870 #define NK_STYLE_PUSH_IMPLEMENATION(prefix, type, stack) \
14871 nk_style_push_##type(struct nk_context *ctx, prefix##_##type *address, prefix##_##type value)\
14873 struct nk_config_stack_##type * type_stack;\
14874 struct nk_config_stack_##type##_element *element;\
14876 if (!ctx) return 0;\
14877 type_stack = &ctx->stacks.stack;\
14878 NK_ASSERT(type_stack->head < (int)NK_LEN(type_stack->elements));\
14879 if (type_stack->head >= (int)NK_LEN(type_stack->elements))\
14881 element = &type_stack->elements[type_stack->head++];\
14882 element->address = address;\
14883 element->old_value = *address;\
14887 #define NK_STYLE_POP_IMPLEMENATION(type, stack) \
14888 nk_style_pop_##type(struct nk_context *ctx)\
14890 struct nk_config_stack_##type *type_stack;\
14891 struct nk_config_stack_##type##_element *element;\
14893 if (!ctx) return 0;\
14894 type_stack = &ctx->stacks.stack;\
14895 NK_ASSERT(type_stack->head > 0);\
14896 if (type_stack->head < 1)\
14898 element = &type_stack->elements[--type_stack->head];\
14899 *element->address = element->old_value;\
14902 NK_API int NK_STYLE_PUSH_IMPLEMENATION(
struct nk, style_item, style_items)
14903 NK_API int NK_STYLE_PUSH_IMPLEMENATION(nk,
float, floats)
14904 NK_API int NK_STYLE_PUSH_IMPLEMENATION(
struct nk, vec2, vectors)
14905 NK_API int NK_STYLE_PUSH_IMPLEMENATION(nk,flags, flags)
14906 NK_API int NK_STYLE_PUSH_IMPLEMENATION(
struct nk,color, colors)
14908 NK_API int NK_STYLE_POP_IMPLEMENATION(style_item, style_items)
14909 NK_API int NK_STYLE_POP_IMPLEMENATION(
float,floats)
14910 NK_API int NK_STYLE_POP_IMPLEMENATION(vec2, vectors)
14911 NK_API int NK_STYLE_POP_IMPLEMENATION(flags,flags)
14912 NK_API int NK_STYLE_POP_IMPLEMENATION(color,colors)
14919 if (!
ctx)
return 0;
14978 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
14979 nk_draw_list_init(&
ctx->draw_list);
14982 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
14987 alloc.userdata.ptr = 0;
14988 alloc.alloc = nk_malloc;
14989 alloc.free = nk_mfree;
14998 if (!memory)
return 0;
14999 nk_setup(
ctx, font);
15010 if (!cmds || !pool)
return 0;
15012 nk_setup(
ctx, font);
15020 nk_pool_init(&
ctx->
pool,
alloc, NK_POOL_DEFAULT_CAPACITY);
15030 if (!
alloc)
return 0;
15031 nk_setup(
ctx, font);
15033 nk_pool_init(&
ctx->
pool,
alloc, NK_POOL_DEFAULT_CAPACITY);
15037 #ifdef NK_INCLUDE_COMMAND_USERDATA
15042 ctx->userdata = handle;
15118 nk_remove_table(iter, it);
15120 nk_free_table(
ctx, it);
15128 nk_remove_window(
ctx, iter);
15129 nk_free_window(
ctx, iter);
15131 }
else iter = iter->
next;
15140 if (!
ctx || !buffer)
return;
15144 buffer->
clip = nk_null_rect;
15159 if (!
ctx || !win)
return;
15175 if (!
ctx || !win)
return;
15186 if (!
ctx || !buffer)
return;
15198 if (!
ctx || !win)
return;
15205 parent_last->
next = buf->
end;
15225 mouse_bounds.w = cursor->size.x;
15226 mouse_bounds.h = cursor->size.y;
15275 if (!
ctx)
return 0;
15287 if (!iter)
return 0;
15316 unsigned int capacity)
15318 nk_zero(pool,
sizeof(*pool));
15319 pool->
alloc = *alloc;
15325 nk_pool_free(
struct nk_pool *pool)
15339 nk_zero(pool,
sizeof(*pool));
15348 nk_pool_alloc(
struct nk_pool *pool)
15354 NK_ASSERT(pool->
pages);
15355 if (!pool->
pages)
return 0;
15362 page->next = pool->
pages;
15363 pool->
pages = page;
15388 elem = nk_pool_alloc(&
ctx->
pool);
15390 if (!elem)
return 0;
15397 if (!elem)
return 0;
15421 nk_link_page_element_into_freelist(
ctx, elem);
15425 {
void *elem_end = (
void*)(elem + 1);
15427 if (elem_end == buffer_end)
15429 else nk_link_page_element_into_freelist(
ctx, elem);}
15445 elem = nk_create_page_element(
ctx);
15446 if (!elem)
return 0;
15455 nk_free_page_element(
ctx, pe);
15493 if (!win || !
ctx)
return 0;
15497 if (!tbl)
return 0;
15498 nk_push_table(win, tbl);
15510 unsigned int i = 0;
15512 for (i = 0; i <
size; ++i) {
15513 if (iter->
keys[i] == name) {
15515 return &iter->
values[i];
15536 elem = nk_create_page_element(
ctx);
15537 if (!elem)
return 0;
15546 nk_free_page_element(
ctx, pe);
15549 nk_panel_has_header(
nk_flags flags,
const char *title)
15596 case NK_PANEL_MENU:
return style->window.menu_border_color;
15619 struct nk_vec2 scrollbar_size;
15620 struct nk_vec2 panel_padding;
15634 font = style->
font;
15639 #ifdef NK_INCLUDE_COMMAND_USERDATA
15644 panel_padding = nk_panel_get_padding(style, panel_type);
15648 int left_mouse_down;
15649 int left_mouse_clicked;
15650 int left_mouse_click_in_cursor;
15657 if (nk_panel_has_header(win->
flags, title)) {
15660 }
else header.h = panel_padding.y;
15667 if (left_mouse_down && left_mouse_click_in_cursor && !left_mouse_clicked) {
15677 layout->
type = panel_type;
15680 layout->
bounds.
x += panel_padding.x;
15681 layout->
bounds.
w -= 2*panel_padding.x;
15683 layout->
border = nk_panel_get_border(style, win->
flags, panel_type);
15685 }
else layout->
border = 0;
15700 layout->
bounds.
w -= scrollbar_size.x;
15701 if (!nk_panel_is_nonblock(panel_type)) {
15709 if (nk_panel_has_header(win->
flags, title))
15724 layout->
bounds.
y += header.h;
15725 layout->
bounds.
h -= header.h;
15726 layout->
at_y += header.h;
15743 text.background =
nk_rgba(0,0,0,0);
15746 text.background = background->
data.
color;
15754 button.w = button.h;
15765 if (nk_do_button_symbol(&ws, &win->
buffer, button,
15778 button.x = (header.w + header.x) - button.w;
15785 button.x = header.x;
15798 struct nk_rect label = {0,0,0,0};
15807 label.
w =
NK_CLAMP(0, label.
w, header.x + header.w - label.
x);
15808 nk_widget_text(out, label,(
const char*)title, text_len, &text,
NK_TEXT_LEFT, font);}
15829 layout->
clip = clip;}
15841 struct nk_vec2 scrollbar_size;
15842 struct nk_vec2 panel_padding;
15851 layout = window->
layout;
15855 if (!nk_panel_is_sub(layout->
type))
15860 panel_padding = nk_panel_get_padding(style, layout->
type);
15874 empty_space.x = window->
bounds.
x;
15875 empty_space.y = layout->
bounds.
y;
15876 empty_space.h = panel_padding.y;
15877 empty_space.w = window->
bounds.
w;
15881 empty_space.x = window->
bounds.
x;
15882 empty_space.y = layout->
bounds.
y;
15883 empty_space.w = panel_padding.x + layout->
border;
15884 empty_space.h = layout->
bounds.
h;
15889 empty_space.y = layout->
bounds.
y;
15890 empty_space.w = panel_padding.x + layout->
border;
15891 empty_space.h = layout->
bounds.
h;
15893 empty_space.w += scrollbar_size.x;
15898 empty_space.x = window->
bounds.
x;
15900 empty_space.w = window->
bounds.
w;
15912 int scroll_has_scrolling;
15913 float scroll_target;
15914 float scroll_offset;
15919 if (nk_panel_is_sub(layout->
type))
15922 struct nk_window *root_window = window;
15924 while (root_panel->
parent)
15925 root_panel = root_panel->
parent;
15926 while (root_window->
parent)
15927 root_window = root_window->
parent;
15930 scroll_has_scrolling = 0;
15938 root_panel = window->
layout;
15939 while (root_panel->
parent) {
15941 root_panel = root_panel->
parent;
15944 scroll_has_scrolling =
nk_true;
15947 }
else if (!nk_panel_is_sub(layout->
type)) {
15953 }
else scroll_has_scrolling =
nk_false;
15958 scroll.x = layout->
bounds.
x + layout->
bounds.
w + panel_padding.x;
15960 scroll.w = scrollbar_size.x;
15963 scroll_offset = (float)*layout->
offset_y;
15964 scroll_step = scroll.h * 0.10f;
15965 scroll_inc = scroll.h * 0.01f;
15966 scroll_target = (
float)(int)(layout->
at_y - scroll.y);
15967 scroll_offset = nk_do_scrollbarv(&state, out, scroll, scroll_has_scrolling,
15968 scroll_offset, scroll_target, scroll_step, scroll_inc,
15971 if (in && scroll_has_scrolling)
15980 scroll.h = scrollbar_size.y;
15982 scroll_offset = (float)*layout->
offset_x;
15983 scroll_target = (
float)(int)(layout->
max_x - scroll.x);
15984 scroll_step = layout->
max_x * 0.05f;
15985 scroll_inc = layout->
max_x * 0.005f;
15986 scroll_offset = nk_do_scrollbarh(&state, out, scroll, scroll_has_scrolling,
15987 scroll_offset, scroll_target, scroll_step, scroll_inc,
15998 if ((!has_input && is_window_hovered) || (!is_window_hovered && !any_item_active))
16006 struct nk_color border_color = nk_panel_get_border_color(style, layout->
type);
16013 b.
h = padding_y - window->
bounds.
y;
16022 scaler.
w = scrollbar_size.x;
16023 scaler.h = scrollbar_size.y;
16026 scaler.x = layout->
bounds.
x - panel_padding.x * 0.5f;
16027 else scaler.x = layout->
bounds.
x + layout->
bounds.
w + panel_padding.x;
16029 scaler.x -= scaler.w;
16038 scaler.y + scaler.h, scaler.x + scaler.w,
16039 scaler.y + scaler.h, item->
data.
color);
16042 scaler.y + scaler.h, scaler.x, scaler.y + scaler.h, item->
data.
color);
16053 if (left_mouse_down && left_mouse_click_in_scaler) {
16056 delta_x = -delta_x;
16060 if (window->
bounds.
w + delta_x >= window_size.
x) {
16061 if ((delta_x < 0) || (delta_x > 0 && in->
mouse.
pos.
x >= scaler.x)) {
16081 if (!nk_panel_is_sub(layout->
type)) {
16084 nk_command_buffer_reset(&window->
buffer);
16086 else nk_finish(
ctx, window);
16108 nk_zero(&window->
edit,
sizeof(window->
edit));
16141 elem = nk_create_page_element(
ctx);
16142 if (!elem)
return 0;
16161 nk_remove_table(win, it);
16162 nk_free_table(
ctx, it);
16171 nk_free_page_element(
ctx, pe);}
16179 NK_ASSERT(iter != iter->
next);
16180 if (iter->
name == hash) {
16191 enum nk_window_insert_location loc)
16196 if (!win || !
ctx)
return;
16200 NK_ASSERT(iter != iter->
next);
16201 NK_ASSERT(iter != win);
16202 if (iter == win)
return;
16214 if (loc == NK_INSERT_BACK) {
16283 NK_ASSERT(!
ctx->
current &&
"if this triggers you missed a `nk_end` call");
16291 win = nk_find_window(
ctx, name_hash, name);
16297 if (!win)
return 0;
16300 nk_insert_window(
ctx, win, NK_INSERT_FRONT);
16301 else nk_insert_window(
ctx, win, NK_INSERT_BACK);
16306 win->
name = name_hash;
16337 }
else nk_start(
ctx, win);
16342 int inpanel, ishovered;
16359 iter_bounds.
x, iter_bounds.
y, iter_bounds.
w, iter_bounds.
h) &&
16373 if (iter && inpanel && (win !=
ctx->
end)) {
16380 iter_bounds.
x, iter_bounds.
y, iter_bounds.
w, iter_bounds.
h) &&
16398 nk_remove_window(
ctx, iter);
16399 nk_insert_window(
ctx, iter, NK_INSERT_BACK);
16402 if (!iter &&
ctx->
end != win) {
16406 nk_remove_window(
ctx, win);
16407 nk_insert_window(
ctx, win, NK_INSERT_BACK);
16428 NK_ASSERT(
ctx->
current &&
"if this triggers you forgot to call `nk_begin`");
16572 if (!
ctx)
return 0;
16599 return any_hovered || any_active;
16608 if (!
ctx)
return 0;
16612 win = nk_find_window(
ctx, title_hash,
name);
16613 if (!win)
return 0;
16623 if (!
ctx)
return 1;
16627 win = nk_find_window(
ctx, title_hash,
name);
16628 if (!win)
return 1;
16638 if (!
ctx)
return 1;
16642 win = nk_find_window(
ctx, title_hash,
name);
16643 if (!win)
return 1;
16653 if (!
ctx)
return 0;
16657 win = nk_find_window(
ctx, title_hash,
name);
16658 if (!win)
return 0;
16668 return nk_find_window(
ctx, title_hash,
name);
16678 NK_ASSERT(
ctx->
current != win &&
"You cannot close a currently active window");
16692 NK_ASSERT(
ctx->
current != win &&
"You cannot update a currently in procecss window");
16737 win = nk_find_window(
ctx, title_hash,
name);
16748 if (!
ctx || !cond)
return;
16762 win = nk_find_window(
ctx, title_hash,
name);
16773 if (!
ctx || !cond)
return;
16788 win = nk_find_window(
ctx, title_hash,
name);
16789 if (win &&
ctx->
end != win) {
16790 nk_remove_window(
ctx, win);
16791 nk_insert_window(
ctx, win, NK_INSERT_BACK);
16833 popup->parent = win;
16855 popup->parent = win;
16856 popup->bounds = rect;
16865 nk_start_popup(
ctx, win);
16925 popup->parent = win;
16931 int pressed, in_body, in_header;
16932 #ifdef NK_BUTTON_TRIGGER_ON_RELEASE
16939 if (pressed && (!in_body || in_header))
16961 NK_ASSERT(popup->
layout);
16963 nk_start_popup(
ctx, win);
16968 nk_panel_begin(
ctx, 0, panel_type);
16991 NK_ASSERT(
popup->parent);
17008 if (!
popup->parent)
return;
17009 win =
popup->parent;
17023 nk_finish_popup(
ctx, win);
17040 *offset_x =
popup->scrollbar.x;
17042 *offset_y =
popup->scrollbar.y;
17056 popup->scrollbar.x = offset_x;
17057 popup->scrollbar.y = offset_y;
17070 struct nk_rect trigger_bounds)
17077 int is_clicked = 0;
17100 if ((!is_open && !is_clicked))
17164 const char *text,
int len,
nk_flags align)
17194 const char *label,
nk_flags align)
17200 const char *text,
int len,
nk_flags align)
17254 NK_ASSERT(popup->
parent);
17262 struct nk_rect body = {0,0,0,0};
17271 if (pressed && in_body)
17360 const char *
id,
int is_clicked,
struct nk_rect header,
struct nk_vec2 size)
17376 body.
y = header.
y + header.
h;
17382 if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
17383 (!is_open && !is_active && !is_clicked))
return 0;
17409 if (!state)
return 0;
17414 return nk_menu_begin(
ctx, win, title, is_clicked, header, size);
17439 if (!state)
return 0;
17444 return nk_menu_begin(
ctx, win,
id, is_clicked, header, size);
17464 if (!state)
return 0;
17469 return nk_menu_begin(
ctx, win,
id, is_clicked, header, size);
17489 if (!state)
return 0;
17495 return nk_menu_begin(
ctx, win, title, is_clicked, header, size);
17521 if (!state)
return 0;
17527 return nk_menu_begin(
ctx, win, title, is_clicked, header, size);
17547 const char *label,
nk_flags align)
17553 const char *text,
int len,
nk_flags align)
17558 const char *text,
int len,
nk_flags align)
17563 const char *label,
nk_flags align)
17622 float total_space,
int columns)
17624 float panel_padding;
17625 float panel_spacing;
17632 padding = nk_panel_get_padding(style, type);
17635 panel_padding = 2 * padding.x;
17636 panel_spacing = (float)
NK_MAX(columns - 1, 0) * spacing.x;
17637 panel_space = total_space - panel_padding - panel_spacing;
17638 return panel_space;
17642 float height,
int cols)
17677 if (height == 0.0f)
17679 else layout->
row.
height = height + item_spacing.y;
17685 background.x = win->
bounds.
x;
17686 background.w = win->
bounds.
w;
17687 background.y = layout->
at_y - 1.0f;
17688 background.h = layout->
row.
height + 1.0f;
17694 float height,
int cols,
int width)
17705 nk_panel_layout(
ctx, win, height, cols);
17720 NK_ASSERT(pixel_width);
17737 float row_height,
int cols)
17750 nk_panel_layout(
ctx, win, row_height, cols);
17780 float ratio = ratio_or_width;
17781 if ((ratio + layout->
row.
filled) > 1.0f)
return;
17809 float height,
int cols,
const float *ratio)
17824 nk_panel_layout(
ctx, win, height, cols);
17829 for (i = 0; i < cols; ++i) {
17830 if (ratio[i] < 0.0f)
17832 else r += ratio[i];
17836 layout->
row.
item_width = (r > 0 && n_undef > 0) ? (r / (
float)n_undef):0;
17860 nk_panel_layout(
ctx, win, height, 1);
17940 int variable_count = 0;
17941 int min_variable_count = 0;
17942 float min_fixed_width = 0.0f;
17943 float total_fixed_width = 0.0f;
17944 float max_variable_width = 0.0f;
17958 if (width >= 0.0f) {
17959 total_fixed_width += width;
17960 min_fixed_width += width;
17961 }
else if (width < -1.0f) {
17963 total_fixed_width += width;
17964 max_variable_width =
NK_MAX(max_variable_width, width);
17967 min_variable_count++;
17971 if (variable_count) {
17972 float space = nk_layout_row_calculate_usable_space(&
ctx->
style, layout->
type,
17974 float var_width = (
NK_MAX(space-min_fixed_width,0.0f)) / (
float)variable_count;
17975 int enough_space = var_width >= max_variable_width;
17977 var_width = (
NK_MAX(space-total_fixed_width,0)) / (
float)min_variable_count;
17980 *width = (*width >= 0.0f)? *width: (*width < -1.0f && !enough_space)? -(*width): var_width;
17986 float height,
int widget_count)
17999 nk_panel_layout(
ctx, win, height, widget_count);
18057 ret.x = layout->
clip.
x;
18058 ret.y = layout->
clip.
y;
18059 ret.w = layout->
clip.
w;
18076 ret.x = layout->
at_x;
18077 ret.y = layout->
at_y;
18151 const float row_height = layout->
row.
height - spacing.
y;
18152 nk_panel_layout(
ctx, win, row_height, layout->
row.
columns);
18164 float item_offset = 0;
18165 float item_width = 0;
18166 float item_spacing = 0;
18167 float panel_space = 0;
18181 padding = nk_panel_get_padding(style, layout->
type);
18182 panel_space = nk_layout_row_calculate_usable_space(&
ctx->
style, layout->
type,
18185 #define NK_FRAC(x) (x - (int)x)
18191 item_offset = (
float)layout->
row.
index * w;
18192 item_width = w + NK_FRAC(item_offset);
18193 item_spacing = (float)layout->
row.
index * spacing.x;
18199 item_width = w + NK_FRAC(item_offset);
18225 w = (ratio * panel_space);
18226 item_spacing = (float)layout->
row.
index * spacing.x;
18228 item_width = w + NK_FRAC(item_offset);
18238 item_offset = (float)layout->
row.
index * item_width;
18239 item_spacing = (
float)layout->
row.
index * spacing.x;
18245 item_spacing = (float)layout->
row.
index * spacing.x;
18252 if (((bounds->
x + bounds->
w) > layout->
max_x) && modify)
18253 layout->
max_x = (bounds->
x + bounds->
w);
18262 item_spacing = (float)layout->
row.
index * spacing.x;
18274 item_width = w + NK_FRAC(item_offset);
18275 item_spacing = (float)layout->
row.
index * spacing.x;
18279 default: NK_ASSERT(0);
break;
18283 bounds->
w = item_width;
18286 bounds->
x = layout->
at_x + item_offset + item_spacing + padding.x;
18287 if (((bounds->
x + bounds->
w) > layout->
max_x) && modify)
18288 layout->
max_x = bounds->
x + bounds->
w;
18307 nk_panel_alloc_row(
ctx, win);
18366 struct nk_rect header = {0,0,0,0};
18367 struct nk_rect sym = {0,0,0,0};
18397 text.background =
nk_rgba(0,0,0,0);
18399 text.background = background->
data.
color;
18430 button, 0, style->
font);
18434 sym.
x = sym.
x + sym.
w + 4 * item_spacing.x;
18441 header.
w =
NK_MAX(header.
w, sym.
w + item_spacing.x);
18442 label.x = sym.
x + sym.
w + item_spacing.x;
18444 label.w = header.
w - (sym.
w + item_spacing.y + style->
tab.
indent);
18448 nk_widget_text(out, label, title,
nk_strlen(title), &text,
18463 const char *hash,
int len,
int line)
18475 state = nk_find_value(win, tree_hash);
18477 state = nk_add_value(
ctx, win, tree_hash, 0);
18478 *state = initial_state;
18486 return nk_tree_state_base(
ctx, type, 0, title, state);
18492 return nk_tree_state_base(
ctx, type, &img, title, state);
18516 const char *hash,
int len,
int line)
18518 return nk_tree_base(
ctx,
type, 0, title, initial_state, hash, len, line);
18523 const char *hash,
int len,
int seed)
18525 return nk_tree_base(
ctx,
type, &img, title, initial_state, hash, len, seed);
18534 struct nk_image *img,
const char *title,
int title_len,
18551 struct nk_rect header = {0,0,0,0};
18552 struct nk_rect sym = {0,0,0,0};
18583 text.background =
nk_rgba(0,0,0,0);
18585 text.background = background->
data.
color;
18620 text_width += (4 * padding.x);
18622 header.
w =
NK_MAX(header.
w, sym.
w + item_spacing.x);
18623 label.x = sym.
x + sym.
w + item_spacing.x;
18625 label.w =
NK_MIN(header.
w - (sym.
w + item_spacing.y + style->
tab.
indent), text_width);
18631 }
else nk_do_selectable(&dummy, &win->
buffer, label, title, title_len,
NK_TEXT_LEFT,
18646 int *selected,
const char *hash,
int len,
int line)
18658 state = nk_find_value(win, tree_hash);
18660 state = nk_add_value(
ctx, win, tree_hash, 0);
18661 *state = initial_state;
18662 }
return nk_tree_element_image_push_hashed_base(
ctx, type, img, title,
18668 int *selected,
const char *hash,
int len,
int seed)
18670 return nk_tree_element_base(
ctx, type, 0, title, initial_state, selected, hash, len, seed);
18675 int *selected,
const char *hash,
int len,
int seed)
18677 return nk_tree_element_base(
ctx, type, &img, title, initial_state, selected, hash, len, seed);
18713 nk_zero(&panel,
sizeof(panel));
18715 panel.
flags = flags;
18716 panel.scrollbar.x = *x_offset;
18717 panel.scrollbar.y = *y_offset;
18719 panel.layout = (
struct nk_panel*)nk_create_panel(
ctx);
18725 panel.layout->
offset_x = x_offset;
18726 panel.layout->
offset_y = y_offset;
18728 win->
layout = panel.layout;
18752 struct nk_vec2 panel_padding;
18771 pan.bounds.x = g->
bounds.
x - panel_padding.x;
18772 pan.bounds.w = g->
bounds.
w + 2 * panel_padding.x;
18775 pan.bounds.x -= g->
border;
18776 pan.bounds.y -= g->
border;
18777 pan.bounds.w += 2*g->
border;
18778 pan.bounds.h += 2*g->
border;
18786 pan.flags = g->
flags;
18787 pan.buffer = win->
buffer;
18793 nk_unify(&clip, &parent->
clip, pan.bounds.
x, pan.bounds.y,
18794 pan.bounds.x + pan.bounds.w, pan.bounds.y + pan.bounds.h + panel_padding.x);
18798 win->
buffer = pan.buffer;
18813 const char *title,
nk_flags flags)
18832 x_offset = nk_find_value(win, id_hash);
18834 x_offset = nk_add_value(
ctx, win, id_hash, 0);
18835 y_offset = nk_add_value(
ctx, win, id_hash+1, 0);
18837 NK_ASSERT(x_offset);
18838 NK_ASSERT(y_offset);
18839 if (!x_offset || !y_offset)
return 0;
18840 *x_offset = *y_offset = 0;
18841 }
else y_offset = nk_find_value(win, id_hash+1);
18874 x_offset_ptr = nk_find_value(win, id_hash);
18875 if (!x_offset_ptr) {
18876 x_offset_ptr = nk_add_value(
ctx, win, id_hash, 0);
18877 y_offset_ptr = nk_add_value(
ctx, win, id_hash+1, 0);
18879 NK_ASSERT(x_offset_ptr);
18880 NK_ASSERT(y_offset_ptr);
18881 if (!x_offset_ptr || !y_offset_ptr)
return;
18882 *x_offset_ptr = *y_offset_ptr = 0;
18883 }
else y_offset_ptr = nk_find_value(win, id_hash+1);
18885 *x_offset = *x_offset_ptr;
18887 *y_offset = *y_offset_ptr;
18909 x_offset_ptr = nk_find_value(win, id_hash);
18910 if (!x_offset_ptr) {
18911 x_offset_ptr = nk_add_value(
ctx, win, id_hash, 0);
18912 y_offset_ptr = nk_add_value(
ctx, win, id_hash+1, 0);
18914 NK_ASSERT(x_offset_ptr);
18915 NK_ASSERT(y_offset_ptr);
18916 if (!x_offset_ptr || !y_offset_ptr)
return;
18917 *x_offset_ptr = *y_offset_ptr = 0;
18918 }
else y_offset_ptr = nk_find_value(win, id_hash+1);
18919 *x_offset_ptr = x_offset;
18920 *y_offset_ptr = y_offset;
18933 const char *title,
nk_flags flags,
int row_height,
int row_count)
18949 if (!
ctx || !view || !title)
return 0;
18954 row_height +=
NK_MAX(0, (
int)item_spacing.y);
18959 x_offset = nk_find_value(win, title_hash);
18961 x_offset = nk_add_value(
ctx, win, title_hash, 0);
18962 y_offset = nk_add_value(
ctx, win, title_hash+1, 0);
18964 NK_ASSERT(x_offset);
18965 NK_ASSERT(y_offset);
18966 if (!x_offset || !y_offset)
return 0;
18967 *x_offset = *y_offset = 0;
18968 }
else y_offset = nk_find_value(win, title_hash+1);
18979 view->
count = (int)
NK_MAX(nk_iceilf((layout->
clip.
h)/(float)row_height),0);
18993 NK_ASSERT(view->
ctx);
18995 if (!view || !view->
ctx)
return;
19022 nk_layout_peek(&bounds,
ctx);
19034 nk_layout_peek(&bounds,
ctx);
19046 nk_layout_peek(&bounds,
ctx);
19058 nk_layout_peek(&bounds,
ctx);
19070 nk_layout_peek(&bounds,
ctx);
19084 c.
x = (float)((
int)c.
x);
19085 c.
y = (float)((
int)c.
y);
19086 c.
w = (float)((
int)c.
w);
19087 c.
h = (float)((
int)c.
h);
19089 nk_layout_peek(&bounds,
ctx);
19090 nk_unify(&v, &c, bounds.
x, bounds.
y, bounds.
x + bounds.
w, bounds.
y + bounds.
h);
19106 c.
x = (float)((
int)c.
x);
19107 c.
y = (float)((
int)c.
y);
19108 c.
w = (float)((
int)c.
w);
19109 c.
h = (float)((
int)c.
h);
19111 nk_layout_peek(&bounds,
ctx);
19112 nk_unify(&v, &c, bounds.
x, bounds.
y, bounds.
x + bounds.
w, bounds.
y + bounds.
h);
19128 c.
x = (float)((
int)c.
x);
19129 c.
y = (float)((
int)c.
y);
19130 c.
w = (float)((
int)c.
w);
19131 c.
h = (float)((
int)c.
h);
19133 nk_layout_peek(&bounds,
ctx);
19134 nk_unify(&v, &c, bounds.
x, bounds.
y, bounds.
x + bounds.
w, bounds.
y + bounds.
h);
19154 nk_panel_alloc_space(bounds,
ctx);
19170 bounds->
x = (float)((
int)bounds->
x);
19171 bounds->
y = (float)((
int)bounds->
y);
19172 bounds->
w = (float)((
int)bounds->
w);
19173 bounds->
h = (float)((
int)bounds->
h);
19175 c.
x = (float)((
int)c.
x);
19176 c.
y = (float)((
int)c.
y);
19177 c.
w = (float)((
int)c.
w);
19178 c.
h = (float)((
int)c.
h);
19180 nk_unify(&v, &c, bounds->
x, bounds->
y, bounds->
x + bounds->
w, bounds->
y + bounds->
h);
19196 struct nk_vec2 panel_padding;
19209 panel_padding = nk_panel_get_padding(style, layout->
type);
19211 bounds->
w += panel_padding.x;
19212 bounds->
x -= panel_padding.x;
19213 }
else bounds->
x -= item_padding.
x;
19216 bounds->
w += panel_padding.x;
19217 else bounds->
w += item_padding.
x;
19226 int i, index, rows;
19240 for (i = 0; i < rows; ++i)
19241 nk_panel_alloc_row(
ctx, win);
19247 for (i = 0; i < cols; ++i)
19248 nk_panel_alloc_space(&none,
ctx);
19263 const char *
string,
int len,
const struct nk_text *t,
19271 if (!o || !t)
return;
19273 b.
h =
NK_MAX(b.
h, 2 * t->padding.y);
19274 label.x = 0; label.w = 0;
19275 label.y = b.
y + t->padding.y;
19279 text_width += (2.0f * t->padding.x);
19283 label.x = b.
x + t->padding.x;
19284 label.w =
NK_MAX(0, b.
w - 2 * t->padding.x);
19286 label.w =
NK_MAX(1, 2 * t->padding.x + (
float)text_width);
19287 label.x = (b.
x + t->padding.x + ((b.
w - 2 * t->padding.x) - label.w) / 2);
19288 label.x =
NK_MAX(b.
x + t->padding.x, label.x);
19289 label.w =
NK_MIN(b.
x + b.
w, label.x + label.w);
19290 if (label.w >= label.x) label.w -= label.x;
19292 label.x =
NK_MAX(b.
x + t->padding.x, (b.
x + b.
w) - (2 * t->padding.x + (
float)text_width));
19293 label.w = (float)text_width + 2 * t->padding.x;
19298 label.y = b.
y + b.
h/2.0f - (float)f->
height/2.0f;
19304 nk_draw_text(o, label, (
const char*)
string, len, f, t->background, t->text);
19308 const char *
string,
int len,
const struct nk_text *t,
19321 if (!o || !t)
return;
19324 text.background = t->background;
19325 text.text = t->text;
19327 b.
w =
NK_MAX(b.
w, 2 * t->padding.x);
19328 b.
h =
NK_MAX(b.
h, 2 * t->padding.y);
19329 b.
h = b.
h - 2 * t->padding.y;
19331 line.x = b.
x + t->padding.x;
19332 line.y = b.
y + t->padding.y;
19333 line.w = b.
w - 2 * t->padding.x;
19334 line.h = 2 * t->padding.y + f->
height;
19336 fitting = nk_text_clamp(f,
string, len, line.w, &glyphs, &width, seperator,
NK_LEN(seperator));
19337 while (done < len) {
19338 if (!fitting || line.y + line.h >= (b.
y + b.
h))
break;
19339 nk_widget_text(o, line, &
string[done], fitting, &text,
NK_TEXT_LEFT, f);
19341 line.y += f->
height + 2 * t->padding.y;
19342 fitting = nk_text_clamp(f, &
string[done], len - done, line.w, &glyphs, &width, seperator,
NK_LEN(seperator));
19363 nk_panel_alloc_space(&bounds,
ctx);
19366 text.padding.
x = item_padding.
x;
19367 text.padding.y = item_padding.
y;
19370 nk_widget_text(&win->
buffer, bounds, str, len, &text, alignment, style->
font);
19390 nk_panel_alloc_space(&bounds,
ctx);
19393 text.padding.
x = item_padding.
x;
19394 text.padding.y = item_padding.
y;
19397 nk_widget_text_wrap(&win->
buffer, bounds, str, len, &text, style->
font);
19399 #ifdef NK_INCLUDE_STANDARD_VARARGS
19402 struct nk_color color,
const char *fmt, ...)
19405 va_start(args, fmt);
19406 nk_labelfv_colored(
ctx, flags, color, fmt, args);
19411 const char *fmt, ...)
19414 va_start(args, fmt);
19415 nk_labelfv_colored_wrap(
ctx, color, fmt, args);
19422 va_start(args, fmt);
19423 nk_labelfv(
ctx, flags, fmt, args);
19427 nk_labelf_wrap(
struct nk_context *
ctx,
const char *fmt,...)
19430 va_start(args, fmt);
19431 nk_labelfv_wrap(
ctx, fmt, args);
19436 struct nk_color color,
const char *fmt, va_list args)
19439 nk_strfmt(buf,
NK_LEN(buf), fmt, args);
19445 const char *fmt, va_list args)
19448 nk_strfmt(buf,
NK_LEN(buf), fmt, args);
19456 nk_strfmt(buf,
NK_LEN(buf), fmt, args);
19461 nk_labelfv_wrap(
struct nk_context *
ctx,
const char *fmt, va_list args)
19464 nk_strfmt(buf,
NK_LEN(buf), fmt, args);
19469 nk_value_bool(
struct nk_context *
ctx,
const char *prefix,
int value)
19471 nk_labelf(
ctx,
NK_TEXT_LEFT,
"%s: %s", prefix, ((value) ?
"true":
"false"));
19474 nk_value_int(
struct nk_context *
ctx,
const char *prefix,
int value)
19479 nk_value_uint(
struct nk_context *
ctx,
const char *prefix,
unsigned int value)
19484 nk_value_float(
struct nk_context *
ctx,
const char *prefix,
float value)
19486 double double_value = (double)value;
19492 nk_labelf(
ctx,
NK_TEXT_LEFT,
"%s: (%d, %d, %d, %d)", p, c.
r, c.
g, c.
b, c.
a);
19499 p, c[0], c[1], c[2], c[3]);
19573 nk_zero(&s,
sizeof(s));
19574 s.handle.ptr = ptr;
19576 s.region[0] = (
unsigned short)r.x;
19577 s.region[1] = (
unsigned short)r.y;
19578 s.region[2] = (
unsigned short)r.w;
19579 s.region[3] = (
unsigned short)r.h;
19586 nk_zero(&s,
sizeof(s));
19589 s.region[0] = (
unsigned short)r.x;
19590 s.region[1] = (
unsigned short)r.y;
19591 s.region[2] = (
unsigned short)r.w;
19592 s.region[3] = (
unsigned short)r.h;
19600 nk_zero(&s,
sizeof(s));
19603 s.region[0] = (
unsigned short)r.x;
19604 s.region[1] = (
unsigned short)r.y;
19605 s.region[2] = (
unsigned short)r.w;
19606 s.region[3] = (
unsigned short)r.h;
19613 nk_zero(&s,
sizeof(s));
19626 nk_zero(&s,
sizeof(s));
19628 s.handle.ptr = ptr;
19640 nk_zero(&s,
sizeof(s));
19653 return !(img->
w == 0 && img->
h == 0);
19711 text.background = background;
19712 text.text = foreground;
19723 nk_fill_rect(out, nk_shrink_rect(content, border_width), 0, background);
19741 points[2].
x, points[2].
y, foreground);
19753 nk_widget_state_reset(state);
19762 #ifdef NK_BUTTON_TRIGGER_ON_RELEASE
19782 background = &style->
hover;
19784 background = &style->
active;
19785 else background = &style->
normal;
19804 if (!out || !style)
19828 background = nk_draw_button(out, bounds, state, style);
19832 text.background = background->
data.
color;
19841 nk_widget_text(out, *content, txt, len, &text, text_alignment, font);
19844 nk_do_button_text(
nk_flags *state,
19858 if (!out || !style || !font || !
string)
19861 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
19863 nk_draw_button_text(out, &bounds, &content, *state, style,
string, len, align, font);
19877 background = nk_draw_button(out, bounds, state, style);
19887 nk_draw_symbol(out,
type, *content, bg, sym, 1, font);
19890 nk_do_button_symbol(
nk_flags *state,
19903 if (!out || !style || !font || !state)
19906 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
19908 nk_draw_button_symbol(out, &bounds, &content, *state, style, symbol, font);
19917 nk_draw_button(out, bounds, state, style);
19921 nk_do_button_image(
nk_flags *state,
19932 if (!out || !style || !state)
19935 ret = nk_do_button(state, out, bounds, style, in, b, &content);
19942 nk_draw_button_image(out, &bounds, &content, *state, style, &img);
19958 background = nk_draw_button(out, bounds, state, style);
19960 text.background = background->
data.
color;
19980 nk_do_button_text_symbol(
nk_flags *state,
19987 struct nk_rect tri = {0,0,0,0};
19993 if (!out || !style || !font)
19996 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
19997 tri.
y = content.
y + (content.
h/2) - font->
height/2;
20000 tri.
x = (content.
x + content.
w) - (2 * style->
padding.
x + tri.
w);
20002 }
else tri.
x = content.
x + 2 * style->
padding.
x;
20006 nk_draw_button_text_symbol(out, &bounds, &content, &tri,
20007 *state, style, str, len, symbol, font);
20015 const char *str,
int len,
const struct nk_user_font *font,
20020 background = nk_draw_button(out, bounds, state, style);
20024 text.background = background->
data.
color;
20037 nk_do_button_text_image(
nk_flags *state,
20051 if (!out || !font || !style || !str)
20054 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
20056 icon.w = icon.h = bounds.
h - 2 * style->
padding.
y;
20058 icon.x = (bounds.
x + bounds.
w) - (2 * style->
padding.
x + icon.w);
20059 icon.x =
NK_MAX(icon.x, 0);
20060 }
else icon.x = bounds.
x + 2 * style->
padding.
x;
20068 nk_draw_button_text_image(out, &bounds, &content, &icon, *state, style, str, len, font, &img);
20082 struct nk_config_stack_button_behavior *button_stack;
20083 struct nk_config_stack_button_behavior_element *element;
20086 if (!
ctx)
return 0;
20089 NK_ASSERT(button_stack->head < (
int)
NK_LEN(button_stack->elements));
20090 if (button_stack->head >= (
int)
NK_LEN(button_stack->elements))
20093 element = &button_stack->elements[button_stack->head++];
20102 struct nk_config_stack_button_behavior *button_stack;
20103 struct nk_config_stack_button_behavior_element *element;
20106 if (!
ctx)
return 0;
20109 NK_ASSERT(button_stack->head > 0);
20110 if (button_stack->head < 1)
20113 element = &button_stack->elements[--button_stack->head];
20114 *element->address = element->old_value;
20138 if (!state)
return 0;
20148 if (!
ctx)
return 0;
20183 if (!state)
return 0;
20215 if (!state)
return 0;
20224 if (!
ctx)
return 0;
20248 if (!state)
return 0;
20257 if (!
ctx)
return 0;
20263 const char *text,
int len,
nk_flags align)
20282 if (!state)
return 0;
20290 const char* text,
int len,
nk_flags align)
20293 if (!
ctx)
return 0;
20297 const char *label,
nk_flags align)
20303 const char *title,
nk_flags align)
20329 if (!state)
return 0;
20337 const char *text,
int len,
nk_flags align)
20342 const char *label,
nk_flags align)
20348 const char *label,
nk_flags text_alignment)
20366 nk_widget_state_reset(state);
20381 const struct nk_rect *cursors,
const char *
string,
int len,
20390 background = &style->
hover;
20394 background = &style->
hover;
20398 background = &style->
normal;
20414 text.padding.x = 0;
20415 text.padding.y = 0;
20417 nk_widget_text(out, *label,
string, len, &text,
NK_TEXT_LEFT, font);
20423 const struct nk_rect *cursors,
const char *
string,
int len,
20432 background = &style->
hover;
20436 background = &style->
hover;
20440 background = &style->
normal;
20456 text.padding.x = 0;
20457 text.padding.y = 0;
20459 nk_widget_text(out, *label,
string, len, &text,
NK_TEXT_LEFT, font);
20464 int *active,
const char *str,
int len,
enum nk_toggle_type type,
20477 if (!out || !style || !font || !active)
20491 select.
h = select.
w;
20492 select.
y = r.
y + r.
h/2.0f - select.
h/2.0f;
20502 label.
x = select.
x + select.
w + style->
spacing;
20503 label.
y = select.
y;
20505 label.
h = select.
w;
20508 was_active = *active;
20509 *active = nk_toggle_behavior(in, bounds, state, *active);
20514 if (type == NK_TOGGLE_CHECK) {
20515 nk_draw_checkbox(out, *state, style, *active, &label, &select, &cursor, str, len, font);
20517 nk_draw_option(out, *state, style, *active, &label, &select, &cursor, str, len, font);
20521 return (was_active != *active);
20550 if (!state)
return active;
20553 text, len, NK_TOGGLE_CHECK, &style->
checkbox, in, style->
font);
20558 unsigned int flags,
unsigned int value)
20563 if (!
ctx || !text)
return flags;
20564 old_active = (int)((flags & value) & value);
20567 else flags &= ~value;
20577 if (!
ctx || !text || !active)
return 0;
20580 return old_val != *active;
20584 unsigned int *flags,
unsigned int value)
20590 if (!
ctx || !text || !flags)
return 0;
20592 active = (int)((*flags & value) & value);
20594 if (active) *flags |= value;
20595 else *flags &= ~value;
20605 unsigned int flags,
unsigned int value)
20614 unsigned int *flags,
unsigned int value)
20645 if (!state)
return (
int)state;
20648 text, len, NK_TOGGLE_OPTION, &style->
option, in, style->
font);
20658 if (!
ctx || !text || !active)
return 0;
20659 old_value = *active;
20661 return old_value != *active;
20686 const struct nk_rect *bounds,
20692 text.padding = style->
padding;
20697 background = &style->
pressed;
20700 background = &style->
hover;
20703 background = &style->
normal;
20721 text.background =
nk_rgba(0,0,0,0);
20724 text.background = background->
data.
color;
20728 else nk_draw_symbol(out, sym, *icon, text.background, text.text, 1, font);
20730 nk_widget_text(out, *bounds,
string, len, &text, align, font);
20734 struct nk_rect bounds,
const char *str,
int len,
nk_flags align,
int *value,
20749 if (!state || !out || !str || !len || !value || !style || !font)
return 0;
20750 old_value = *value;
20760 *value = !(*value);
20764 nk_draw_selectable(out, *state, style, *value, &bounds, 0,0,
NK_SYMBOL_NONE, str, len, align, font);
20766 return old_value != *value;
20770 struct nk_rect bounds,
const char *str,
int len,
nk_flags align,
int *value,
20786 if (!state || !out || !str || !len || !value || !style || !font)
return 0;
20787 old_value = *value;
20795 *value = !(*value);
20798 icon.
w = icon.
h = bounds.
h - 2 * style->
padding.
y;
20800 icon.
x = (bounds.
x + bounds.
w) - (2 * style->
padding.
x + icon.
w);
20802 }
else icon.
x = bounds.
x + 2 * style->
padding.
x;
20811 nk_draw_selectable(out, *state, style, *value, &bounds, &icon, img,
NK_SYMBOL_NONE, str, len, align, font);
20813 return old_value != *value;
20817 struct nk_rect bounds,
const char *str,
int len,
nk_flags align,
int *value,
20833 if (!state || !out || !str || !len || !value || !style || !font)
return 0;
20834 old_value = *value;
20842 *value = !(*value);
20845 icon.
w = icon.
h = bounds.
h - 2 * style->
padding.
y;
20847 icon.
x = (bounds.
x + bounds.
w) - (2 * style->
padding.
x + icon.
w);
20849 }
else icon.
x = bounds.
x + 2 * style->
padding.
x;
20858 nk_draw_selectable(out, *state, style, *value, &bounds, &icon, 0, sym, str, len, align, font);
20860 return old_value != *value;
20887 if (!state)
return 0;
20894 const char *str,
int len,
nk_flags align,
int *value)
20916 if (!state)
return 0;
20919 str, len, align, value, &img, &style->
selectable, in, style->
font);
20923 const char *str,
int len,
nk_flags align,
int *value)
20945 if (!state)
return 0;
20948 str, len, align, value, sym, &style->
selectable, in, style->
font);
20952 const char *title,
nk_flags align,
int *value)
20966 const char *str,
nk_flags align,
int *value)
20975 const char *str,
nk_flags align,
int value)
20980 const char *str,
int len,
nk_flags align,
int value)
20986 const char *title,
int title_len,
nk_flags align,
int value)
20992 const char *title,
nk_flags align,
int value)
21009 struct nk_rect bounds,
float slider_min,
float slider_max,
float slider_value,
21010 float slider_step,
float slider_steps)
21012 int left_mouse_down;
21013 int left_mouse_click_in_cursor;
21016 nk_widget_state_reset(state);
21021 if (left_mouse_down && left_mouse_click_in_cursor) {
21023 const float d = in->
mouse.
pos.
x - (visual_cursor->
x+visual_cursor->
w*0.5f);
21024 const float pxstep = bounds.
w / slider_steps;
21028 if (
NK_ABS(d) >= pxstep) {
21029 const float steps = (float)((
int)(
NK_ABS(d) / pxstep));
21030 slider_value += (d > 0) ? (slider_step*steps) : -(slider_step*steps);
21031 slider_value =
NK_CLAMP(slider_min, slider_value, slider_max);
21032 ratio = (slider_value - slider_min)/slider_step;
21033 logical_cursor->
x = bounds.
x + (logical_cursor->
w * ratio);
21046 return slider_value;
21051 const struct nk_rect *visual_cursor,
float min,
float value,
float max)
21066 background = &style->
active;
21070 background = &style->
hover;
21074 background = &style->
normal;
21080 bar.y = (visual_cursor->
y + visual_cursor->
h/2) - bounds->
h/12;
21082 bar.h = bounds->
h/6;
21085 fill.w = (visual_cursor->
x + (visual_cursor->
w/2.0f)) - bar.x;
21110 float min,
float val,
float max,
float step,
21114 float slider_range;
21117 float slider_value;
21118 float slider_steps;
21119 float cursor_offset;
21121 struct nk_rect visual_cursor;
21122 struct nk_rect logical_cursor;
21126 if (!out || !style)
21141 button.y = bounds.
y;
21142 button.w = bounds.
h;
21143 button.h = bounds.
h;
21146 button.x = bounds.
x;
21152 button.x = (bounds.
x + bounds.
w) - button.w;
21157 bounds.
x = bounds.
x + button.w + style->
spacing.
x;
21158 bounds.
w = bounds.
w - (2*button.w + 2*style->
spacing.
x);
21166 slider_max =
NK_MAX(min, max);
21167 slider_min =
NK_MIN(min, max);
21168 slider_value =
NK_CLAMP(slider_min, val, slider_max);
21169 slider_range = slider_max - slider_min;
21170 slider_steps = slider_range / step;
21171 cursor_offset = (slider_value - slider_min) / step;
21176 logical_cursor.
h = bounds.
h;
21177 logical_cursor.
w = bounds.
w / slider_steps;
21178 logical_cursor.
x = bounds.
x + (logical_cursor.
w * cursor_offset);
21179 logical_cursor.
y = bounds.
y;
21183 visual_cursor.
y = (bounds.
y + bounds.
h*0.5f) - visual_cursor.
h*0.5f;
21184 visual_cursor.
x = logical_cursor.
x - visual_cursor.
w*0.5f;
21186 slider_value = nk_slider_behavior(state, &logical_cursor, &visual_cursor,
21187 in, bounds, slider_min, slider_max, slider_value, step, slider_steps);
21188 visual_cursor.
x = logical_cursor.
x - visual_cursor.
w*0.5f;
21192 nk_draw_slider(out, *state, style, &bounds, &visual_cursor, slider_min, slider_value, slider_max);
21194 return slider_value;
21222 if (!state)
return ret;
21225 old_value = *value;
21227 old_value, max_value, value_step, &style->
slider, in, style->
font);
21228 return (old_value > *value || old_value < *value);
21238 float value = (float)val;
21246 float value = (float)*val;
21265 int left_mouse_down = 0;
21266 int left_mouse_click_in_cursor = 0;
21268 nk_widget_state_reset(state);
21269 if (!in || !modifiable)
return value;
21276 if (in && left_mouse_down && left_mouse_click_in_cursor) {
21277 if (left_mouse_down && left_mouse_click_in_cursor) {
21278 float ratio =
NK_MAX(0, (
float)(in->
mouse.
pos.
x - cursor.
x)) / (float)cursor.
w;
21304 background = &style->
active;
21307 background = &style->
hover;
21310 background = &style->
normal;
21338 if (!out || !style)
return 0;
21344 prog_scale = (float)value / (
float)max;
21347 prog_value =
NK_MIN(value, max);
21348 prog_value = nk_progress_behavior(state, in, bounds, cursor,max, prog_value, modifiable);
21349 cursor.w = cursor.w * prog_scale;
21353 nk_draw_progress(out, *state, style, &bounds, &cursor, value, max);
21380 if (!state)
return 0;
21385 *cur, max, is_modifyable, &style->
progress, in);
21386 return (*cur != old_value);
21406 int has_scrolling,
const struct nk_rect *scroll,
21408 const struct nk_rect *empty1,
float scroll_offset,
21412 int left_mouse_down;
21413 int left_mouse_clicked;
21414 int left_mouse_click_in_cursor;
21415 float scroll_delta;
21417 nk_widget_state_reset(state);
21418 if (!in)
return scroll_offset;
21428 if (left_mouse_down && left_mouse_click_in_cursor && !left_mouse_clicked) {
21430 float pixel, delta;
21435 delta = (pixel / scroll->
h) * target;
21436 scroll_offset =
NK_CLAMP(0, scroll_offset + delta, target - scroll->
h);
21437 cursor_y = scroll->
y + ((scroll_offset/target) * scroll->
h);
21442 delta = (pixel / scroll->
w) * target;
21443 scroll_offset =
NK_CLAMP(0, scroll_offset + delta, target - scroll->
w);
21444 cursor_x = scroll->
x + ((scroll_offset/target) * scroll->
w);
21451 scroll_offset =
NK_MAX(0, scroll_offset - scroll->
h);
21452 else scroll_offset =
NK_MAX(0, scroll_offset - scroll->
w);
21457 scroll_offset =
NK_MIN(scroll_offset + scroll->
h, target - scroll->
h);
21458 else scroll_offset =
NK_MIN(scroll_offset + scroll->
w, target - scroll->
w);
21459 }
else if (has_scrolling) {
21460 if ((scroll_delta < 0 || (scroll_delta > 0))) {
21462 scroll_offset = scroll_offset + scroll_step * (-scroll_delta);
21464 scroll_offset =
NK_CLAMP(0, scroll_offset, target - scroll->
h);
21465 else scroll_offset =
NK_CLAMP(0, scroll_offset, target - scroll->
w);
21471 if (o ==
NK_VERTICAL) scroll_offset = target - scroll->
h;
21478 return scroll_offset;
21483 const struct nk_rect *scroll)
21490 background = &style->
active;
21493 background = &style->
hover;
21496 background = &style->
normal;
21517 float offset,
float target,
float step,
float button_pixel_inc,
21526 float scroll_offset;
21528 float scroll_ratio;
21533 if (!out || !style)
return 0;
21537 if (target <= scroll.
h)
return 0;
21545 button.x = scroll.
x;
21546 button.w = scroll.
w;
21547 button.h = scroll.
w;
21549 scroll_h =
NK_MAX(scroll.
h - 2 * button.h,0);
21550 scroll_step =
NK_MIN(step, button_pixel_inc);
21553 button.y = scroll.
y;
21554 if (nk_do_button_symbol(&ws, out, button, style->
dec_symbol,
21556 offset = offset - scroll_step;
21559 button.y = scroll.
y + scroll.
h - button.h;
21560 if (nk_do_button_symbol(&ws, out, button, style->
inc_symbol,
21562 offset = offset + scroll_step;
21564 scroll.
y = scroll.
y + button.h;
21565 scroll.
h = scroll_h;
21569 scroll_step =
NK_MIN(step, scroll.
h);
21570 scroll_offset =
NK_CLAMP(0, offset, target - scroll.
h);
21571 scroll_ratio = scroll.
h / target;
21572 scroll_off = scroll_offset / target;
21576 cursor.y = scroll.
y + (scroll_off * scroll.
h) + style->
border + style->
padding.
y;
21581 empty_north.x = scroll.
x;
21582 empty_north.y = scroll.
y;
21583 empty_north.w = scroll.
w;
21584 empty_north.h =
NK_MAX(cursor.y - scroll.
y, 0);
21586 empty_south.x = scroll.
x;
21587 empty_south.y = cursor.y + cursor.h;
21588 empty_south.w = scroll.
w;
21589 empty_south.h =
NK_MAX((scroll.
y + scroll.
h) - (cursor.y + cursor.h), 0);
21592 scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor,
21593 &empty_north, &empty_south, scroll_offset, target, scroll_step,
NK_VERTICAL);
21594 scroll_off = scroll_offset / target;
21599 nk_draw_scrollbar(out, *state, style, &scroll, &cursor);
21601 return scroll_offset;
21606 float offset,
float target,
float step,
float button_pixel_inc,
21615 float scroll_offset;
21617 float scroll_ratio;
21621 if (!out || !style)
return 0;
21625 scroll.
w =
NK_MAX(scroll.
w, 2 * scroll.
h);
21626 if (target <= scroll.
w)
return 0;
21633 button.y = scroll.
y;
21634 button.w = scroll.
h;
21635 button.h = scroll.
h;
21637 scroll_w = scroll.
w - 2 * button.w;
21638 scroll_step =
NK_MIN(step, button_pixel_inc);
21641 button.x = scroll.
x;
21642 if (nk_do_button_symbol(&ws, out, button, style->
dec_symbol,
21644 offset = offset - scroll_step;
21647 button.x = scroll.
x + scroll.
w - button.w;
21648 if (nk_do_button_symbol(&ws, out, button, style->
inc_symbol,
21650 offset = offset + scroll_step;
21652 scroll.
x = scroll.
x + button.w;
21653 scroll.
w = scroll_w;
21657 scroll_step =
NK_MIN(step, scroll.
w);
21658 scroll_offset =
NK_CLAMP(0, offset, target - scroll.
w);
21659 scroll_ratio = scroll.
w / target;
21660 scroll_off = scroll_offset / target;
21663 cursor.w = (scroll_ratio * scroll.
w) - (2*style->
border + 2*style->
padding.
x);
21664 cursor.x = scroll.
x + (scroll_off * scroll.
w) + style->
border + style->
padding.
x;
21669 empty_west.x = scroll.
x;
21670 empty_west.y = scroll.
y;
21671 empty_west.w = cursor.x - scroll.
x;
21672 empty_west.h = scroll.
h;
21674 empty_east.x = cursor.x + cursor.w;
21675 empty_east.y = scroll.
y;
21676 empty_east.w = (scroll.
x + scroll.
w) - (cursor.x + cursor.w);
21677 empty_east.h = scroll.
h;
21680 scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor,
21681 &empty_west, &empty_east, scroll_offset, target, scroll_step,
NK_HORIZONTAL);
21682 scroll_off = scroll_offset / target;
21683 cursor.x = scroll.
x + (scroll_off * scroll.
w);
21687 nk_draw_scrollbar(out, *state, style, &scroll, &cursor);
21689 return scroll_offset;
21702 struct nk_text_find {
21705 int first_char, length;
21709 struct nk_text_edit_row {
21712 float baseline_y_delta;
21723 #define NK_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
21726 nk_textedit_get_width(
const struct nk_text_edit *edit,
int line_start,
int char_id,
21735 nk_textedit_layout_row(
struct nk_text_edit_row *r,
struct nk_text_edit *edit,
21736 int line_start_id,
float row_height,
const struct nk_user_font *font)
21741 const char *remaining;
21745 const struct nk_vec2 size = nk_text_calculate_text_bounds(font,
21746 text, (
int)(end - text), row_height, &remaining, 0, &glyphs, NK_STOP_ON_NEW_LINE);
21750 r->baseline_y_delta = size.
y;
21753 r->num_chars = glyphs;
21756 nk_textedit_locate_coord(
struct nk_text_edit *edit,
float x,
float y,
21759 struct nk_text_edit_row r;
21761 float base_y = 0, prev_x;
21765 r.ymin = r.ymax = 0;
21770 nk_textedit_layout_row(&r, edit, i, row_height, font);
21771 if (r.num_chars <= 0)
21774 if (i==0 && y < base_y + r.ymin)
21777 if (y < base_y + r.ymax)
21781 base_y += r.baseline_y_delta;
21797 for (i=0; i < r.num_chars; ++i) {
21798 float w = nk_textedit_get_width(edit, k, i, font);
21799 if (x < prev_x+w) {
21800 if (x < prev_x+w/2)
21812 return i+r.num_chars-1;
21813 else return i+r.num_chars;
21816 nk_textedit_click(
struct nk_text_edit *state,
float x,
float y,
21821 state->
cursor = nk_textedit_locate_coord(state, x, y, font, row_height);
21827 nk_textedit_drag(
struct nk_text_edit *state,
float x,
float y,
21832 int p = nk_textedit_locate_coord(state, x, y, font, row_height);
21838 nk_textedit_find_charpos(
struct nk_text_find *find,
struct nk_text_edit *state,
21839 int n,
int single_line,
const struct nk_user_font *font,
float row_height)
21843 struct nk_text_edit_row r;
21844 int prev_start = 0;
21852 nk_textedit_layout_row(&r, state, 0, row_height, font);
21854 find->first_char = 0;
21860 nk_textedit_layout_row(&r, state, i, row_height, font);
21863 find->first_char = i;
21864 find->length = r.num_chars;
21868 find->height = r.ymax - r.ymin;
21869 find->prev_first = prev_start;
21877 nk_textedit_layout_row(&r, state, i, row_height, font);
21878 if (n < i + r.num_chars)
break;
21881 find->y += r.baseline_y_delta;
21884 find->first_char = first = i;
21885 find->length = r.num_chars;
21886 find->height = r.ymax - r.ymin;
21887 find->prev_first = prev_start;
21891 for (i=0; first+i < n; ++i)
21892 find->x += nk_textedit_get_width(state, first, i, font);
21899 if (NK_TEXT_HAS_SELECTION(state)) {
21912 nk_textedit_makeundo_delete(state, where, len);
21920 nk_textedit_clamp(state);
21921 if (NK_TEXT_HAS_SELECTION(state)) {
21948 if (NK_TEXT_HAS_SELECTION(state)) {
21949 nk_textedit_sortselection(state);
21959 if (NK_TEXT_HAS_SELECTION(state)) {
21960 nk_textedit_sortselection(state);
21961 nk_textedit_clamp(state);
21968 nk_is_word_boundary(
struct nk_text_edit *state,
int idx)
21972 if (idx <= 0)
return 1;
21974 return (c ==
' ' || c ==
'\t' ||c == 0x3000 || c ==
',' || c ==
';' ||
21975 c ==
'(' || c ==
')' || c ==
'{' || c ==
'}' || c ==
'[' || c ==
']' ||
21979 nk_textedit_move_to_word_previous(
struct nk_text_edit *state)
21981 int c = state->
cursor - 1;
21982 while( c >= 0 && !nk_is_word_boundary(state, c))
21991 nk_textedit_move_to_word_next(
struct nk_text_edit *state)
21994 int c = state->
cursor+1;
21995 while( c < len && !nk_is_word_boundary(state, c))
22004 nk_textedit_prep_selection_at_cursor(
struct nk_text_edit *state)
22007 if (!NK_TEXT_HAS_SELECTION(state))
22017 if (NK_TEXT_HAS_SELECTION(state)) {
22029 const char *text = (
const char *) ctext;
22033 nk_textedit_clamp(state);
22039 nk_textedit_makeundo_insert(state, state->
cursor, glyphs);
22061 while ((text_len < total_len) && glyph_len)
22064 if (unicode == 127)
goto next;
22066 if (unicode ==
'\n' && state->
single_line)
goto next;
22068 if (state->
filter && !state->
filter(state, unicode))
goto next;
22070 if (!NK_TEXT_HAS_SELECTION(state) &&
22074 nk_textedit_makeundo_replace(state, state->
cursor, 1, 1);
22088 nk_textedit_makeundo_insert(state, state->
cursor, 1);
22094 text_len += glyph_len;
22095 glyph_len =
nk_utf_decode(text + text_len, &unicode, total_len-text_len);
22146 nk_textedit_clamp(state);
22147 nk_textedit_prep_selection_at_cursor(state);
22156 if (NK_TEXT_HAS_SELECTION(state))
22157 nk_textedit_move_to_first(state);
22158 else if (state->
cursor > 0)
22165 nk_textedit_prep_selection_at_cursor(state);
22168 nk_textedit_clamp(state);
22174 if (NK_TEXT_HAS_SELECTION(state))
22175 nk_textedit_move_to_last(state);
22177 nk_textedit_clamp(state);
22183 if( !NK_TEXT_HAS_SELECTION( state ) )
22184 nk_textedit_prep_selection_at_cursor(state);
22185 state->
cursor = nk_textedit_move_to_word_previous(state);
22187 nk_textedit_clamp(state );
22189 if (NK_TEXT_HAS_SELECTION(state))
22190 nk_textedit_move_to_first(state);
22192 state->
cursor = nk_textedit_move_to_word_previous(state);
22193 nk_textedit_clamp(state );
22199 if( !NK_TEXT_HAS_SELECTION( state ) )
22200 nk_textedit_prep_selection_at_cursor(state);
22201 state->
cursor = nk_textedit_move_to_word_next(state);
22203 nk_textedit_clamp(state);
22205 if (NK_TEXT_HAS_SELECTION(state))
22206 nk_textedit_move_to_last(state);
22208 state->
cursor = nk_textedit_move_to_word_next(state);
22209 nk_textedit_clamp(state );
22214 struct nk_text_find find;
22215 struct nk_text_edit_row row;
22216 int i, sel = shift_mod;
22225 nk_textedit_prep_selection_at_cursor(state);
22226 else if (NK_TEXT_HAS_SELECTION(state))
22227 nk_textedit_move_to_last(state);
22230 nk_textedit_clamp(state);
22239 int start = find.first_char + find.length;
22242 nk_textedit_layout_row(&row, state, state->
cursor, row_height, font);
22245 for (i=0; i < row.num_chars && x < row.x1; ++i) {
22246 float dx = nk_textedit_get_width(state, start, i, font);
22252 nk_textedit_clamp(state);
22262 struct nk_text_find find;
22263 struct nk_text_edit_row row;
22264 int i, sel = shift_mod;
22273 nk_textedit_prep_selection_at_cursor(state);
22274 else if (NK_TEXT_HAS_SELECTION(state))
22275 nk_textedit_move_to_first(state);
22278 nk_textedit_clamp(state);
22283 if (find.prev_first != find.first_char) {
22288 state->
cursor = find.prev_first;
22289 nk_textedit_layout_row(&row, state, state->
cursor, row_height, font);
22292 for (i=0; i < row.num_chars && x < row.x1; ++i) {
22293 float dx = nk_textedit_get_width(state, find.prev_first, i, font);
22299 nk_textedit_clamp(state);
22310 if (NK_TEXT_HAS_SELECTION(state))
22323 if (NK_TEXT_HAS_SELECTION(state))
22326 nk_textedit_clamp(state);
22327 if (state->
cursor > 0) {
22337 nk_textedit_prep_selection_at_cursor(state);
22348 nk_textedit_prep_selection_at_cursor(state);
22360 struct nk_text_find find;
22361 nk_textedit_clamp(state);
22362 nk_textedit_prep_selection_at_cursor(state);
22370 struct nk_text_find find;
22373 nk_textedit_clamp(state);
22374 nk_textedit_move_to_first(state);
22377 state->
cursor = find.first_char;
22384 struct nk_text_find find;
22385 nk_textedit_clamp(state);
22386 nk_textedit_prep_selection_at_cursor(state);
22390 state->
cursor = find.first_char + find.length;
22395 struct nk_text_find find;
22396 nk_textedit_clamp(state);
22397 nk_textedit_move_to_first(state);
22402 state->
cursor = find.first_char + find.length;
22472 nk_textedit_flush_redo(state);
22477 nk_textedit_discard_undo(state);
22490 nk_textedit_discard_undo(state);
22495 int insert_len,
int delete_len)
22505 if (insert_len == 0) {
22529 r->
where = u.where;
22531 if (u.delete_length)
22550 nk_textedit_discard_redo(s);
22561 for (i=0; i < u.delete_length; ++i)
22570 if (u.insert_length) {
22573 &s->
undo_char[u.char_storage], u.insert_length);
22576 state->
cursor = (short)(u.where + u.insert_length);
22633 nk_textedit_createundo(&state->
undo,
where, 0, length);
22641 for (i=0; i < length; ++i)
22647 int old_length,
int new_length)
22650 nk_rune *p = nk_textedit_createundo(&state->
undo,
where, old_length, new_length);
22652 for (i=0; i < old_length; ++i)
22681 if (!state || !memory || !size)
return;
22691 if (!state || !alloc)
return;
22696 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
22701 if (!state)
return;
22704 nk_str_init_default(&state->
string);
22718 if (!state)
return;
22742 if (unicode > 128)
return nk_false;
22749 if ((unicode < '0' || unicode >
'9') && unicode !=
'.' && unicode !=
'-')
22757 if ((unicode < '0' || unicode >
'9') && unicode !=
'-')
22765 if ((unicode < '0' || unicode >
'9') &&
22766 (unicode < 'a' || unicode >
'f') &&
22767 (unicode < 'A' || unicode >
'F'))
22775 if (unicode < '0' || unicode >
'7')
22783 if (unicode !=
'0' && unicode !=
'1')
22795 const struct nk_style_edit *style,
float pos_x,
float pos_y,
22796 float x_offset,
const char *text,
int byte_len,
float row_height,
22798 struct nk_color foreground,
int is_selected)
22803 if (!text || !byte_len || !out || !style)
return;
22805 {
int glyph_len = 0;
22808 float line_width = 0;
22810 const char *line = text;
22811 float line_offset = 0;
22812 int line_count = 0;
22816 txt.background = background;
22817 txt.text = foreground;
22819 glyph_len =
nk_utf_decode(text+text_len, &unicode, byte_len-text_len);
22820 if (!glyph_len)
return;
22821 while ((text_len < byte_len) && glyph_len)
22823 if (unicode ==
'\n') {
22826 label.
y = pos_y + line_offset;
22827 label.h = row_height;
22828 label.w = line_width;
22831 label.x += x_offset;
22835 nk_widget_text(out, label, line, (
int)((text + text_len) - line),
22841 line = text + text_len;
22842 line_offset += row_height;
22843 glyph_len =
nk_utf_decode(text + text_len, &unicode, (
int)(byte_len-text_len));
22846 if (unicode ==
'\r') {
22848 glyph_len =
nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
22852 line_width += (float)glyph_width;
22853 text_len += glyph_len;
22854 glyph_len =
nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
22857 if (line_width > 0) {
22860 label.
y = pos_y + line_offset;
22861 label.h = row_height;
22862 label.w = line_width;
22865 label.x += x_offset;
22869 nk_widget_text(out, label, line, (
int)((text + text_len) - line),
22882 char prev_state = 0;
22883 char is_hovered = 0;
22884 char select_all = 0;
22885 char cursor_follow = 0;
22892 if (!state || !out || !style)
22905 old_clip = out->
clip;
22906 nk_unify(&clip, &old_clip, area.x, area.y, area.x + area.w, area.y + area.h);
22909 prev_state = (char)edit->
active;
22913 bounds.
x, bounds.
y, bounds.
w, bounds.
h);
22917 if (!prev_state && edit->
active) {
22920 nk_textedit_clear_state(edit, type, filter);
22934 if (prev_state != edit->
active)
22950 nk_textedit_click(edit, mouse_x, mouse_y, font, row_height);
22953 nk_textedit_drag(edit, mouse_x, mouse_y, font, row_height);
22963 int old_mode = edit->
mode;
22967 nk_textedit_key(edit, (
enum nk_keys)i, shift_mod, font, row_height);
22971 if (old_mode != edit->
mode) {
23004 int begin =
NK_MIN(b, e);
23033 else nk_widget_state_reset(state);
23045 background = &style->
active;
23047 background = &style->
hover;
23048 else background = &style->
normal;
23059 int total_lines = 1;
23063 const char *cursor_ptr = 0;
23064 const char *select_begin_ptr = 0;
23065 const char *select_end_ptr = 0;
23076 float line_width = 0.0f;
23092 while ((text_len < len) && glyph_len)
23095 if (!cursor_ptr && glyphs == edit->
cursor)
23100 const char *remaining;
23103 cursor_pos.
y = (float)(total_lines-1) * row_height;
23104 row_size = nk_text_calculate_text_bounds(font, text+row_begin,
23105 text_len-row_begin, row_height, &remaining,
23106 &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
23107 cursor_pos.
x = row_size.x;
23108 cursor_ptr = text + text_len;
23113 glyphs == selection_begin)
23118 const char *remaining;
23121 selection_offset_start.
y = (float)(
NK_MAX(total_lines-1,0)) * row_height;
23122 row_size = nk_text_calculate_text_bounds(font, text+row_begin,
23123 text_len-row_begin, row_height, &remaining,
23124 &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
23125 selection_offset_start.
x = row_size.x;
23126 select_begin_ptr = text + text_len;
23131 glyphs == selection_end)
23136 const char *remaining;
23139 selection_offset_end.
y = (float)(total_lines-1) * row_height;
23140 row_size = nk_text_calculate_text_bounds(font, text+row_begin,
23141 text_len-row_begin, row_height, &remaining,
23142 &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
23143 selection_offset_end.
x = row_size.x;
23144 select_end_ptr = text + text_len;
23146 if (unicode ==
'\n') {
23147 text_size.
x =
NK_MAX(text_size.
x, line_width);
23152 row_begin = text_len;
23153 glyph_len =
nk_utf_decode(text + text_len, &unicode, len-text_len);
23159 text_len += glyph_len;
23160 line_width += (float)glyph_width;
23162 glyph_len =
nk_utf_decode(text + text_len, &unicode, len-text_len);
23164 text+text_len, glyph_len);
23167 text_size.
y = (float)total_lines * row_height;
23171 cursor_pos.
x = line_width;
23172 cursor_pos.
y = text_size.
y - row_height;
23182 const float scroll_increment = area.w * 0.25f;
23203 float scroll_target;
23204 float scroll_offset;
23213 scroll_step = scroll.
h * 0.10f;
23214 scroll_inc = scroll.
h * 0.01f;
23215 scroll_target = text_size.
y;
23216 edit->
scrollbar.
y = nk_do_scrollbarv(&ws, out, scroll, 0,
23217 scroll_offset, scroll_target, scroll_step, scroll_inc,
23223 {
struct nk_color background_color;
23225 struct nk_color sel_background_color;
23228 struct nk_color cursor_text_color;
23234 background = &style->
active;
23241 background = &style->
hover;
23248 background = &style->
normal;
23256 background_color =
nk_rgba(0,0,0,0);
23257 else background_color = background->
data.
color;
23264 nk_edit_draw_text(out, style, area.x - edit->
scrollbar.
x,
23265 area.y - edit->
scrollbar.
y, 0, begin, l, row_height, font,
23266 background_color, text_color,
nk_false);
23272 NK_ASSERT(select_begin_ptr);
23273 nk_edit_draw_text(out, style, area.x - edit->
scrollbar.
x,
23274 area.y - edit->
scrollbar.
y, 0, begin, (
int)(select_begin_ptr - begin),
23275 row_height, font, background_color, text_color,
nk_false);
23279 NK_ASSERT(select_begin_ptr);
23280 if (!select_end_ptr) {
23284 nk_edit_draw_text(out, style,
23286 area.y + selection_offset_start.
y - edit->
scrollbar.
y,
23287 selection_offset_start.
x,
23288 select_begin_ptr, (
int)(select_end_ptr - select_begin_ptr),
23289 row_height, font, sel_background_color, sel_text_color,
nk_true);
23292 selection_end < edit->
string.len))
23295 const char *begin = select_end_ptr;
23298 NK_ASSERT(select_end_ptr);
23299 nk_edit_draw_text(out, style,
23301 area.y + selection_offset_end.
y - edit->
scrollbar.
y,
23302 selection_offset_end.
x,
23303 begin, (
int)(end - begin), row_height, font,
23304 background_color, text_color,
nk_true);
23312 (cursor_ptr && *cursor_ptr ==
'\n')) {
23316 cursor.h = font->
height;
23317 cursor.x = area.x + cursor_pos.
x - edit->
scrollbar.
x;
23318 cursor.y = area.y + cursor_pos.
y + row_height/2.0f - cursor.h/2.0f;
23328 NK_ASSERT(cursor_ptr);
23331 label.x = area.x + cursor_pos.
x - edit->
scrollbar.
x;
23332 label.y = area.y + cursor_pos.
y - edit->
scrollbar.
y;
23334 label.h = row_height;
23337 txt.background = cursor_color;;
23338 txt.text = cursor_text_color;
23340 nk_widget_text(out, label, cursor_ptr, glyph_len, &txt,
NK_TEXT_LEFT, font);
23353 background = &style->
active;
23356 background = &style->
hover;
23359 background = &style->
normal;
23363 background_color =
nk_rgba(0,0,0,0);
23364 else background_color = background->
data.
color;
23365 nk_edit_draw_text(out, style, area.x - edit->
scrollbar.
x,
23366 area.y - edit->
scrollbar.
y, 0, begin, l, row_height, font,
23367 background_color, text_color,
nk_false);
23413 if (!
ctx || !memory || !len)
23441 *len =
NK_MIN(*len, max-1);
23446 *len = (int)
edit->string.buffer.allocated;
23469 unsigned char prev_state;
23483 if (!state)
return state;
23502 prev_state = (
unsigned char)edit->
active;
23505 filter, edit, &style->
edit, in, style->
font);
23513 }
else if (prev_state && !edit->
active) {
23516 }
return ret_flags;
23540 struct nk_rect drag,
struct nk_property_variant *variant,
23541 float inc_per_pixel)
23544 int left_mouse_click_in_cursor = in &&
23547 nk_widget_state_reset(state);
23551 if (left_mouse_down && left_mouse_click_in_cursor) {
23552 float delta, pixels;
23554 delta = pixels * inc_per_pixel;
23555 switch (variant->kind) {
23557 case NK_PROPERTY_INT:
23558 variant->value.i = variant->value.i + (int)delta;
23559 variant->value.i =
NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
23561 case NK_PROPERTY_FLOAT:
23562 variant->value.f = variant->value.f + (float)delta;
23563 variant->value.f =
NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
23565 case NK_PROPERTY_DOUBLE:
23566 variant->value.d = variant->value.d + (double)delta;
23567 variant->value.d =
NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
23580 struct nk_rect empty,
int *state,
struct nk_property_variant *variant,
23581 float inc_per_pixel)
23583 if (in && *state == NK_PROPERTY_DEFAULT) {
23585 *state = NK_PROPERTY_EDIT;
23587 *state = NK_PROPERTY_DRAG;
23589 *state = NK_PROPERTY_DRAG;
23591 if (*state == NK_PROPERTY_DRAG) {
23592 nk_drag_behavior(ws, in, property, variant, inc_per_pixel);
23599 const char *name,
int len,
const struct nk_user_font *font)
23606 background = &style->
active;
23609 background = &style->
hover;
23612 background = &style->
normal;
23619 text.background =
nk_rgba(0,0,0,0);
23621 text.background = background->
data.
color;
23633 const char *name,
struct nk_property_variant *variant,
23634 float inc_per_pixel,
char *buffer,
int *len,
23635 int *state,
int *cursor,
int *select_begin,
int *select_end,
23637 enum nk_property_filter filter,
struct nk_input *in,
23646 int num_len, name_len;
23663 left.y =
property.y + style->
border +
property.h/2.0f - left.h/2;
23668 label.
x = left.x + left.w + style->
padding.
x;
23669 label.
w = (float)size + 2 * style->
padding.
x;
23677 right.x =
property.x +
property.w - (right.w + style->
padding.
x);
23680 if (*state == NK_PROPERTY_EDIT) {
23686 switch (variant->kind) {
23688 case NK_PROPERTY_INT:
23689 nk_itoa(
string, variant->value.i);
23692 case NK_PROPERTY_FLOAT:
23693 NK_DTOA(
string, (
double)variant->value.f);
23696 case NK_PROPERTY_DOUBLE:
23697 NK_DTOA(
string, variant->value.d);
23706 edit.
w = (float)size + 2 * style->
padding.
x;
23707 edit.
w =
NK_MIN(edit.
w, right.x - (label.
x + label.
w));
23708 edit.
x = right.x - (edit.
w + style->
padding.
x);
23709 edit.
y =
property.y + style->
border;
23710 edit.
h =
property.h - (2 * style->
border);
23713 empty.
w = edit.
x - (label.
x + label.
w);
23714 empty.
x = label.
x + label.
w;
23715 empty.
y =
property.y;
23716 empty.
h =
property.h;
23719 old = (*state == NK_PROPERTY_EDIT);
23720 nk_property_behavior(ws, in, property, label, edit, empty, state, variant, inc_per_pixel);
23724 nk_draw_property(out, style, &property, &label, *ws, name, name_len, font);
23728 if (nk_do_button_symbol(ws, out, left, style->
sym_left, behavior, &style->
dec_button, in, font)) {
23729 switch (variant->kind) {
23731 case NK_PROPERTY_INT:
23732 variant->value.i =
NK_CLAMP(variant->min_value.i, variant->value.i - variant->step.i, variant->max_value.i);
break;
23733 case NK_PROPERTY_FLOAT:
23734 variant->value.f =
NK_CLAMP(variant->min_value.f, variant->value.f - variant->step.f, variant->max_value.f);
break;
23735 case NK_PROPERTY_DOUBLE:
23736 variant->value.d =
NK_CLAMP(variant->min_value.d, variant->value.d - variant->step.d, variant->max_value.d);
break;
23740 if (nk_do_button_symbol(ws, out, right, style->
sym_right, behavior, &style->
inc_button, in, font)) {
23741 switch (variant->kind) {
23743 case NK_PROPERTY_INT:
23744 variant->value.i =
NK_CLAMP(variant->min_value.i, variant->value.i + variant->step.i, variant->max_value.i);
break;
23745 case NK_PROPERTY_FLOAT:
23746 variant->value.f =
NK_CLAMP(variant->min_value.f, variant->value.f + variant->step.f, variant->max_value.f);
break;
23747 case NK_PROPERTY_DOUBLE:
23748 variant->value.d =
NK_CLAMP(variant->min_value.d, variant->value.d + variant->step.d, variant->max_value.d);
break;
23751 if (old != NK_PROPERTY_EDIT && (*state == NK_PROPERTY_EDIT)) {
23753 NK_MEMCPY(buffer, dst, (
nk_size)*length);
23759 }
else active = (*state == NK_PROPERTY_EDIT);
23763 text_edit->
active = (
unsigned char)active;
23774 filters[filter], text_edit, &style->
edit, (*state == NK_PROPERTY_EDIT) ? in: 0, font);
23777 *cursor = text_edit->
cursor;
23783 if (active && !text_edit->
active) {
23785 *state = NK_PROPERTY_DEFAULT;
23786 buffer[*len] =
'\0';
23787 switch (variant->kind) {
23789 case NK_PROPERTY_INT:
23790 variant->value.i =
nk_strtoi(buffer, 0);
23791 variant->value.i =
NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
23793 case NK_PROPERTY_FLOAT:
23795 variant->value.f =
nk_strtof(buffer, 0);
23796 variant->value.f =
NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
23798 case NK_PROPERTY_DOUBLE:
23800 variant->value.d =
nk_strtod(buffer, 0);
23801 variant->value.d =
NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
23806 NK_LIB struct nk_property_variant
23807 nk_property_variant_int(int value, int min_value, int max_value, int step)
23809 struct nk_property_variant result;
23810 result.kind = NK_PROPERTY_INT;
23811 result.value.i = value;
23812 result.min_value.i = min_value;
23813 result.max_value.i = max_value;
23814 result.step.i = step;
23817 NK_LIB struct nk_property_variant
23818 nk_property_variant_float(float value, float min_value, float max_value, float step)
23820 struct nk_property_variant result;
23821 result.kind = NK_PROPERTY_FLOAT;
23822 result.value.f = value;
23823 result.min_value.f = min_value;
23824 result.max_value.f = max_value;
23825 result.step.f = step;
23828 NK_LIB struct nk_property_variant
23829 nk_property_variant_double(double value, double min_value, double max_value,
23832 struct nk_property_variant result;
23833 result.kind = NK_PROPERTY_DOUBLE;
23834 result.value.d = value;
23835 result.min_value.d = min_value;
23836 result.max_value.d = max_value;
23837 result.step.d = step;
23841 nk_property(
struct nk_context *
ctx,
const char *name,
struct nk_property_variant *variant,
23842 float inc_per_pixel,
const enum nk_property_filter filter)
23857 int *select_begin = 0;
23858 int *select_end = 0;
23862 int dummy_state = NK_PROPERTY_DEFAULT;
23863 int dummy_length = 0;
23864 int dummy_cursor = 0;
23865 int dummy_select_begin = 0;
23866 int dummy_select_end = 0;
23881 if (name[0] ==
'#') {
23895 buffer = dummy_buffer;
23896 len = &dummy_length;
23897 cursor = &dummy_cursor;
23898 state = &dummy_state;
23899 select_begin = &dummy_select_begin;
23900 select_end = &dummy_select_end;
23904 old_state = *state;
23909 variant, inc_per_pixel, buffer, len, state, cursor, select_begin,
23913 if (in && *state != NK_PROPERTY_DEFAULT && !win->
property.
active) {
23923 if (*state == NK_PROPERTY_DRAG) {
23929 if (*state == NK_PROPERTY_DEFAULT && old_state != NK_PROPERTY_DEFAULT) {
23930 if (old_state == NK_PROPERTY_DRAG) {
23942 int min,
int *val,
int max,
int step,
float inc_per_pixel)
23944 struct nk_property_variant variant;
23950 variant = nk_property_variant_int(*val, min, max, step);
23951 nk_property(
ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
23952 *val = variant.value.i;
23956 float min,
float *val,
float max,
float step,
float inc_per_pixel)
23958 struct nk_property_variant variant;
23964 variant = nk_property_variant_float(*val, min, max, step);
23965 nk_property(
ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
23966 *val = variant.value.f;
23970 double min,
double *val,
double max,
double step,
float inc_per_pixel)
23972 struct nk_property_variant variant;
23978 variant = nk_property_variant_double(*val, min, max, step);
23979 nk_property(
ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
23980 *val = variant.value.d;
23984 int max,
int step,
float inc_per_pixel)
23986 struct nk_property_variant variant;
23991 variant = nk_property_variant_int(val, min, max, step);
23992 nk_property(
ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
23993 val = variant.value.i;
23998 float val,
float max,
float step,
float inc_per_pixel)
24000 struct nk_property_variant variant;
24005 variant = nk_property_variant_float(val, min, max, step);
24006 nk_property(
ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
24007 val = variant.value.f;
24012 double val,
double max,
double step,
float inc_per_pixel)
24014 struct nk_property_variant variant;
24019 variant = nk_property_variant_double(val, min, max, step);
24020 nk_property(
ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
24021 val = variant.value.d;
24037 int count,
float min_value,
float max_value)
24045 struct nk_rect bounds = {0, 0, 0, 0};
24054 nk_zero(chart,
sizeof(*chart));
24061 style = &config->
chart;
24064 nk_zero(chart,
sizeof(*chart));
24078 slot->
min =
NK_MIN(min_value, max_value);
24079 slot->
max =
NK_MAX(min_value, max_value);
24095 int count,
float min_value,
float max_value)
24103 int count,
float min_value,
float max_value)
24119 slot->
min =
NK_MIN(min_value, max_value);
24120 slot->
max =
NK_MAX(min_value, max_value);
24125 int count,
float min_value,
float max_value)
24132 struct nk_chart *g,
float value,
int slot)
24147 step =
g->w / (float)
g->slots[slot].count;
24148 range =
g->slots[slot].max -
g->slots[slot].min;
24149 ratio = (value -
g->slots[slot].min) / range;
24151 if (
g->slots[slot].index == 0) {
24153 g->slots[slot].last.x =
g->x;
24154 g->slots[slot].last.y = (
g->y +
g->h) - ratio * (
float)
g->h;
24156 bounds.
x =
g->slots[slot].last.x - 2;
24157 bounds.
y =
g->slots[slot].last.y - 2;
24158 bounds.
w = bounds.
h = 4;
24160 color =
g->slots[slot].color;
24166 color =
g->slots[slot].highlight;
24169 g->slots[slot].index += 1;
24174 color =
g->slots[slot].color;
24175 cur.x =
g->x + (float)(step * (
float)
g->slots[slot].index);
24176 cur.y = (
g->y +
g->h) - (ratio * (
float)
g->h);
24177 nk_stroke_line(out,
g->slots[slot].last.x,
g->slots[slot].last.y, cur.x, cur.y, 1.0f, color);
24179 bounds.
x = cur.x - 3;
24180 bounds.
y = cur.y - 3;
24181 bounds.
w = bounds.
h = 6;
24189 color =
g->slots[slot].highlight;
24195 g->slots[slot].last.x = cur.x;
24196 g->slots[slot].last.y = cur.y;
24197 g->slots[slot].index += 1;
24202 struct nk_chart *chart,
float value,
int slot)
24211 struct nk_rect item = {0,0,0,0};
24217 float padding = (float)(chart->
slots[slot].
count-1);
24218 item.
w = (chart->
w - padding) / (
float)(chart->
slots[slot].
count);
24226 item.
y = (chart->
y + chart->
h) - chart->
h * ratio;
24229 item.
y = chart->
y + (chart->
h *
NK_ABS(ratio)) - item.
h;
24231 item.
x = chart->
x + ((float)chart->
slots[slot].
index * item.
w);
24255 NK_ASSERT(slot < ctx->current->layout->chart.slot);
24290 NK_MEMSET(chart, 0,
sizeof(*chart));
24295 int count,
int offset)
24303 if (!
ctx || !values || !count)
return;
24305 min_value = values[offset];
24306 max_value = values[offset];
24307 for (i = 0; i < count; ++i) {
24308 min_value =
NK_MIN(values[i + offset], min_value);
24309 max_value =
NK_MAX(values[i + offset], max_value);
24313 for (i = 0; i < count; ++i)
24320 float(*value_getter)(
void* user,
int index),
int count,
int offset)
24327 NK_ASSERT(value_getter);
24328 if (!
ctx || !value_getter || !count)
return;
24330 max_value = min_value = value_getter(userdata, offset);
24331 for (i = 0; i < count; ++i) {
24332 float value = value_getter(userdata, i + offset);
24333 min_value =
NK_MIN(value, min_value);
24334 max_value =
NK_MAX(value, max_value);
24338 for (i = 0; i < count; ++i)
24354 nk_color_picker_behavior(
nk_flags *state,
24360 int value_changed = 0;
24361 int hsv_changed = 0;
24365 NK_ASSERT(hue_bar);
24373 value_changed = hsv_changed = 1;
24378 value_changed = hsv_changed = 1;
24387 nk_widget_state_reset(state);
24392 if (value_changed) {
24393 color->
a = hsva[3];
24403 return value_changed;
24414 const float crosshair_size = 7.0f;
24422 NK_ASSERT(hue_bar);
24426 for (i = 0; i < 6; ++i) {
24428 {255, 0, 0, 255}, {255,255,0,255}, {0,255,0,255}, {0, 255,255,255},
24429 {0,0,255,255}, {255, 0, 255, 255}, {255, 0, 0, 255}
24432 nk_rect(hue_bar->
x, hue_bar->
y + (
float)i * (hue_bar->
h/6.0f) + 0.5f,
24433 hue_bar->
w, (hue_bar->
h/6.0f) + 0.5f), hue_colors[i], hue_colors[i],
24434 hue_colors[i+1], hue_colors[i+1]);
24436 line_y = (float)(
int)(hue_bar->
y + hsva[0] * matrix->
h + 0.5f);
24438 line_y, 1,
nk_rgb(255,255,255));
24443 line_y = (float)(
int)(alpha_bar->
y + (1.0f - alpha) * matrix->
h + 0.5f);
24447 line_y, 1,
nk_rgb(255,255,255));
24451 temp =
nk_hsv_f(hsva[0], 1.0f, 1.0f);
24456 {
struct nk_vec2 p;
float S = hsva[1];
float V = hsva[2];
24457 p.
x = (float)(
int)(matrix->
x + S * matrix->
w);
24458 p.y = (float)(
int)(matrix->
y + (1.0f - V) * matrix->
h);
24459 nk_stroke_line(o, p.x - crosshair_size, p.y, p.x-2, p.y, 1.0f, white);
24460 nk_stroke_line(o, p.x + crosshair_size + 1, p.y, p.x+3, p.y, 1.0f, white);
24461 nk_stroke_line(o, p.x, p.y + crosshair_size + 1, p.x, p.y+3, 1.0f, white);
24462 nk_stroke_line(o, p.x, p.y - crosshair_size, p.x, p.y-2, 1.0f, white);}
24465 nk_do_color_picker(
nk_flags *state,
24481 if (!out || !col || !state || !font)
24485 bounds.
x += padding.
x;
24486 bounds.
y += padding.
x;
24487 bounds.
w -= 2 * padding.
x;
24488 bounds.
h -= 2 * padding.
y;
24490 matrix.
x = bounds.
x;
24491 matrix.
y = bounds.
y;
24492 matrix.
h = bounds.
h;
24493 matrix.
w = bounds.
w - (3 * padding.
x + 2 * bar_w);
24496 hue_bar.
y = bounds.
y;
24497 hue_bar.
h = matrix.
h;
24498 hue_bar.
x = matrix.
x + matrix.
w + padding.
x;
24500 alpha_bar.
x = hue_bar.
x + hue_bar.
w + padding.
x;
24501 alpha_bar.
y = bounds.
y;
24502 alpha_bar.
w = bar_w;
24503 alpha_bar.
h = matrix.
h;
24505 ret = nk_color_picker_behavior(state, &bounds, &matrix, &hue_bar,
24506 (fmt ==
NK_RGBA) ? &alpha_bar:0, col, in);
24507 nk_draw_color_picker(out, &matrix, &hue_bar, (fmt ==
NK_RGBA) ? &alpha_bar:0, *col);
24533 if (!state)
return 0;
24580 if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
24581 (!is_open && !is_active && !is_clicked))
return 0;
24582 if (!nk_nonblock_begin(
ctx, 0, body,
24604 NK_ASSERT(selected);
24632 text.background =
nk_rgba(0,0,0,0);
24635 text.background = background->
data.
color;
24648 else if (is_clicked)
24656 button.h = button.w;
24669 nk_widget_text(&win->
buffer, label, selected, len, &text,
24676 return nk_combo_begin(
ctx, win, size, is_clicked, header);
24732 else if (is_clicked)
24740 button.h = button.w;
24758 return nk_combo_begin(
ctx, win, size, is_clicked, header);
24803 sym_background =
nk_rgba(0,0,0,0);
24806 sym_background = background->
data.
color;
24811 struct nk_rect bounds = {0,0,0,0};
24818 else if (is_clicked)
24826 button.h = button.w;
24838 nk_draw_symbol(&win->
buffer, symbol, bounds, sym_background, symbol_color,
24839 1.0f, style->
font);
24845 return nk_combo_begin(
ctx, win, size, is_clicked, header);
24892 text.background =
nk_rgba(0,0,0,0);
24895 text.background = background->
data.
color;
24908 else if (is_clicked)
24916 button.h = button.w;
24930 nk_draw_symbol(&win->
buffer, symbol, image, text.background, symbol_color,
24931 1.0f, style->
font);
24941 return nk_combo_begin(
ctx, win, size, is_clicked, header);
24985 struct nk_rect bounds = {0,0,0,0};
24992 else if (is_clicked)
25000 button.h = button.w;
25018 return nk_combo_begin(
ctx, win, size, is_clicked, header);
25061 text.background =
nk_rgba(0,0,0,0);
25064 text.background = background->
data.
color;
25077 else if (is_clicked)
25085 button.h = button.w;
25109 return nk_combo_begin(
ctx, win, size, is_clicked, header);
25141 const char *text,
nk_flags alignment)
25147 const char *text,
int len,
nk_flags alignment)
25153 const char *label,
nk_flags alignment)
25167 int selected,
int item_height,
struct nk_vec2 size)
25172 struct nk_vec2 window_padding;
25177 if (!
ctx || !items ||!count)
25182 max_height = count * item_height + count * (int)item_spacing.y;
25183 max_height += (
int)item_spacing.y * 2 + (int)window_padding.y * 2;
25184 size.
y =
NK_MIN(size.
y, (
float)max_height);
25187 for (i = 0; i < count; ++i) {
25197 int separator,
int selected,
int count,
int item_height,
struct nk_vec2 size)
25202 struct nk_vec2 window_padding;
25203 const char *current_item;
25208 NK_ASSERT(items_separated_by_separator);
25209 if (!
ctx || !items_separated_by_separator)
25215 max_height = count * item_height + count * (int)item_spacing.y;
25216 max_height += (
int)item_spacing.y * 2 + (int)window_padding.y * 2;
25217 size.
y =
NK_MIN(size.
y, (
float)max_height);
25220 current_item = items_separated_by_separator;
25221 for (i = 0; i < count; ++i) {
25222 iter = current_item;
25223 while (*iter && *iter != separator) iter++;
25224 length = (int)(iter - current_item);
25225 if (i == selected)
break;
25226 current_item = iter + 1;
25230 current_item = items_separated_by_separator;
25232 for (i = 0; i < count; ++i) {
25233 iter = current_item;
25234 while (*iter && *iter != separator) iter++;
25235 length = (int)(iter - current_item);
25238 current_item = current_item + length + 1;
25246 int selected,
int count,
int item_height,
struct nk_vec2 size)
25248 return nk_combo_separator(
ctx, items_separated_by_zeros,
'\0', selected, count, item_height, size);
25252 void *userdata,
int selected,
int count,
int item_height,
struct nk_vec2 size)
25257 struct nk_vec2 window_padding;
25261 NK_ASSERT(item_getter);
25262 if (!
ctx || !item_getter)
25268 max_height = count * item_height + count * (int)item_spacing.y;
25269 max_height += (
int)item_spacing.y * 2 + (int)window_padding.y * 2;
25270 size.
y =
NK_MIN(size.
y, (
float)max_height);
25272 item_getter(userdata, selected, &item);
25275 for (i = 0; i < count; ++i) {
25276 item_getter(userdata, i, &item);
25285 int *selected,
int item_height,
struct nk_vec2 size)
25287 *selected =
nk_combo(
ctx, items, count, *selected, item_height, size);
25291 int *selected,
int count,
int item_height,
struct nk_vec2 size)
25293 *selected =
nk_combo_string(
ctx, items_separated_by_zeros, *selected, count, item_height, size);
25297 int separator,
int *selected,
int count,
int item_height,
struct nk_vec2 size)
25300 *selected, count, item_height, size);
25304 void(*item_getter)(
void* data,
int id,
const char **out_text),
25305 void *userdata,
int *selected,
int count,
int item_height,
struct nk_vec2 size)
25307 *selected =
nk_combo_callback(
ctx, item_getter, userdata, *selected, count, item_height, size);
25340 w = nk_iceilf(width);
25341 h = nk_iceilf(nk_null_rect.h);
25345 bounds.
x = (
float)
x;
25346 bounds.
y = (float)
y;
25347 bounds.
w = (float)
w;
25348 bounds.
h = (float)
h;
25393 text_width += (4 * padding.
x);
25394 text_height = (style->
font->
height + 2 * padding.
y);
25403 #ifdef NK_INCLUDE_STANDARD_VARARGS
25408 va_start(args, fmt);
25409 nk_tooltipfv(
ctx, fmt, args);
25413 nk_tooltipfv(
struct nk_context *
ctx,
const char *fmt, va_list args)
25416 nk_strfmt(buf,
NK_LEN(buf), fmt, args);